【问题标题】:Assign module method to a Class variable or Instance variable将模块方法分配给类变量或实例变量
【发布时间】:2017-12-27 05:55:05
【问题描述】:

在模块 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__ 的情况下将模块级函数分配给类变量,而当我可以分配给实例变量的同一个函数正在工作时。

【问题讨论】:

  • 另外,值得注意的是,它可以在 python 3.x(特别是 3.6)中按预期编译和工作。

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


【解决方案1】:

因为您将函数映射为A 的未绑定方法,所以当您调用cls.func 时,您首先询问等于getattr(cls, 'func') 的内容,它返回&lt;unbound method A.task&gt; 但是,此未绑定方法需要使用类作为调用第一个参数。

所以因为在这种特定情况下cls.func 表示“给我cls 的类属性func”它不能同时表示“调用类方法func” - 所以Python 不翻译@ 987654329@func(cls)

但在同一时间内,因为func&lt;unbound method A.task&gt;(绑定到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 会删除未绑定的方法,这仅适用于 python2.x

【讨论】:

  • 这是什么来源
猜你喜欢
  • 2017-10-27
  • 2018-10-24
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 2021-06-18
  • 1970-01-01
  • 2011-12-19
相关资源
最近更新 更多