4

我知道必须有办法做到这一点。但我收到错误“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')
4

3 回答 3

4

staticmethod对象不可调用。它们是在其属性中保留对原始函数的引用的描述符。__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')
于 2016-04-28T18:21:33.107 回答
3

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

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

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

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

于 2016-04-28T18:27:41.873 回答
2

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

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')
于 2016-04-28T18:32:49.863 回答