考虑以下课程:
class Foo(object):
def bar(self):
print(self)
在Python 2 (2.7.13)中,将bar()
作为类方法调用会引发异常:
>>> Foo.bar('hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got str instance instead)
>>> Foo.bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)
当bar()
作为实例方法调用时,它会在不带参数的情况下将self
识别为实例
>>> Foo().bar('hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() takes exactly 1 argument (2 given)
>>> Foo().bar()
<__main__.Foo object at 0x10a8e1a10>
在Python 3 (3.6.0)中,当调用bar()
作为类方法时,第一个参数被接受为self
:
>>> Foo.bar('hello')
hello
>>> Foo.bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() missing 1 required positional argument: 'self'
将bar()
作为实例方法调用,就像在Python 2中一样工作
>>> Foo().bar('hello')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bar() takes 1 positional argument but 2 were given
>>> Foo().bar()
<__main__.Foo object at 0x104ab34a8>
答案 0 :(得分:9)
在Python 3上,Foo.bar
就是您编写的bar
函数。它需要一个参数,恰好命名为self
,并打印出来。你可以在任何东西上调用该函数,它会打印你传递的任何参数。
在Python 2上,Foo.bar
并不是您编写的bar
函数。当您访问Foo.bar
时,Python会生成一个包含bar
函数的未绑定方法对象。未绑定的方法对象的工作方式与bar
函数类似,主要区别在于验证其第一个参数是Foo
的实例。你可以做到
Foo.bar(some_foo_instance)
可以像some_foo_instance.bar()
一样工作,但调用Foo
的实现,绕过子类中的任何覆盖。但是,你无法做Foo.bar('hello')
。
Python 3 removed unbound method objects.他们不再存在。这使得语言更简单,但它删除了用于执行的验证未绑定方法对象。