【问题标题】:Python functools.partial - How to apply it to a class method with the static decoratorPython functools.partial - 如何使用静态装饰器将其应用于类方法
【发布时间】:2016-08-23 16:22:01
【问题描述】:

我知道一定有办法做到这一点。但我收到错误“TypeError:第一个参数必须是可调用的”。

我可以做些什么不同的事情来完成这项工作?

class FaxMachine(object):
    MODEL_NO = '100'

    @staticmethod
    def load_fax(fax, error=''):
        # send fax here

    fail_fax = functools.partial(load_fax, error='PC LOAD LETTER')

【问题讨论】:

    标签: python static-methods python-decorators functools


    【解决方案1】:

    staticmethod 对象不可调用。它们是 descriptors,在其 __func__ 属性中保留对原始函数的引用。

    所以以下工作:

    # Note: apply staticmethod again
    fail_fax = staticmethod(partial(load_fax.__func__, error='PC LOAD LETTER'))
    

    您还可以在类命名空间中定义一个辅助函数,以避免不必要的属性查找:

    def _load_fax(fax, error=''):
        # ...
    
    # _load_fax is an ordinary function
    load_fax = staticmethod(_load_fax)
    fail_fax = staticmethod(partial(_load_fax, error='PC LOAD LETTER'))
    

    虽然正确的 Python 3.4+ 解决方案是使用 partialmethod,它旨在使用描述符:

    fail_fax = partialmethod(load_fax, error='PC LOAD LETTER')
    

    【讨论】:

      【解决方案2】:

      “调用”时方法和函数的行为不同:使用__call__ 直接调用函数,而__get__ 调用方法(通常不是方法,我认为只有描述符)。

      因此functools-module 包含另一个partial 方法:functools.partialmethod

      functools.partialmethod(load_fax, error='PC LOAD LETTER')
      

      官方文档包含一个很好的解释,尤其是关于staticmethod

      【讨论】:

      【解决方案3】:

      可能有一种更聪明的方法可以做到这一点,但这似乎工作正常。

      import functools
      
      class FaxMachine(object):
          MODEL_NO = '100'
      
          @staticmethod
          def load_fax(fax, error=''):
              print error or fax
      
      FaxMachine.fail_fax = functools.partial(FaxMachine.load_fax, error='PC LOAD LETTER')
      
      f = FaxMachine()
      f.load_fax('hi')
      f.fail_fax('hi')
      

      【讨论】:

        猜你喜欢
        • 2020-11-30
        • 2016-07-24
        • 1970-01-01
        • 1970-01-01
        • 2016-03-17
        • 2014-03-20
        • 2016-05-19
        • 2011-09-18
        • 2016-12-31
        相关资源
        最近更新 更多