python - 将模块方法分配给类变量或实例变量

标签 python python-2.7 class class-variables class-instance-variables

在模块a.py

def task(): 
    print "task called"

a = task

class A:

    func = task              # this show error unbound method
    #func = task.__call__    # if i replace with this work

    def __init__(self):
        self.func_1 = task

    def test_1(self):
        self.func_1()

    @classmethod
    def test(cls):
        cls.func()


a()
A().test_1()
A.test()

输出:

task called
task called
Traceback (most recent call last):
  File "a.py", line 26, in <module>
     A.test()
  File "a.py", line 21, in test
     cls.func()
TypeError: unbound method task() must be called with A instance as 
first argument (got nothing instead)

在模块中,我可以轻松地将函数分配给变量。当类内部尝试将模块级函数分配给类变量时 func = task 它显示错误,要删除此错误我必须将其替换为 func = task.__call__ 但是当我将其工作分配给实例变量 self.func_1 = task

我的问题是:为什么我不能在没有 __call__ 的情况下将模块级函数分配给类变量,而当我可以分配给实例变量的相同函数正在工作时。

最佳答案

因为您将函数映射为 A 的未绑定(bind)方法, 所以当你调用 cls.func你首先问一些等于 getattr(cls, 'func') 的东西返回 <unbound method A.task>但是,这个未绑定(bind)的方法需要以类作为第一个参数来调用。

所以因为在这种特定情况下 cls.func意味着“给我 func 的类属性 cls” 它不能意味着同时“调用类方法 func” - 所以 Python 不会翻译 cls.func()通过 func(cls) .

但同时,因为func<unbound method A.task> (绑定(bind)到 A.task )它需要被称为 func(cls)去工作。

用类似的东西检查它:

@classmethod
def test(cls):
    print getattr(cls, 'func') # <unbound method A.task>

你可以用类似的东西修复它:

def task(cls=None):
    if cls is None:
        print 'task()'
    else:
        print 'A.foo({})'.format(cls)

a = task

class A:
    func = task             # this show error unbound method

    def __init__(self):
        self.func_1 = task

    def test_1(self):
        self.func_1()

    @classmethod
    def test(cls):
        cls.func(cls())

a()
A().test_1()
A.test()

输出:

task()
task()
A.foo(<__main__.A instance at 0x7fd0310a46c8>)

请注意,python3 删除了未绑定(bind)的方法,这仅适用于 python2.x

关于python - 将模块方法分配给类变量或实例变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45233274/

相关文章:

python - 为什么 raw_input 失败了?

python - 为什么我的 PyQt 代码在多线程时不能完全执行?

javascript - 具有特定类名的 Div 的元素

python - SQLAlchemy 中使用 keys() 的列名顺序

Python 程序重命名文件名,如果已经存在该文件则覆盖

c++ - 递归函数中的类变量访问

java - 将类作为方法中的参数传递并在 If 语句中使用此参数

python - 使用 Python 在 Tkinter 中保存异常

python - pySerial问题: embedded controller stops echoing commands

python-2.7 - 来自列表理解的Python字符串