“unbound method”的含义在 Python2 和 Python3 中是否已经改变

2018-05-06 16:17:30 +08:00
 u2386

以下是通过 inspect 库获取类内方法的两端代码:

Python2

>>> class A(object):
...     def a(self):
...         print('a')
...
...     @staticmethod
...     def b():
...         print('b')
...
...     @classmethod
...     def c(cls):
...         print('c')
...
>>> import inspect
>>> inspect.getmembers(A, inspect.ismethod)
[('a', <unbound method A.a>), ('c', <bound method type.c of <class '__main__.A'>>)]

Python3

>>> class A(object):
...     def a(self):
...         print('a')
...
...     @staticmethod
...     def b():
...         print('b')
...
...     @classmethod
...     def c(cls):
...         print('c')
...
>>> import inspect
>>> inspect.getmembers(A, inspect.ismethod)
[('c', <bound method A.c of <class '__main__.A'>>)]

可以看到对于类而言,实例方法在 Python3 中已经不再是method,而是function

>>> inspect.getmembers(A, inspect.isfunction)
[('a', <function A.a at 0x10d46e598>), ('b', <function A.b at 0x10d46e620>)]

通过查阅两个版本的 inspect 文档可以看到在Python2中:

inspect.ismethod(object)

Return true if the object is a bound or unbound method written in Python.

相对于在Python3中:

inspect.ismethod(object)

Return true if the object is a bound method written in Python.

ismethod不在包含 unbound method 了。

这是否是 Python2 到 Python3 后的通识区别?可惜这么重要的区别并没有被大多数的 “ Differences between Python2 and Python3 ” 之类的文章提到。

2763 次点击
所在节点    Python
6 条回复
locktionc
2018-05-06 16:27:28 +08:00
你这个发现非常好。
chenxytw
2018-05-06 16:33:10 +08:00
不是通识区别.....
因为这个已经是比较高级的应用了 0 0 不是那种所有程序员都必须懂的知识......

可以看这封 dev 邮件
https://mail.python.org/pipermail/python-dev/2009-February/086233.html
简言之, unbound method 其实在 Python3 中已经遗弃了,没有这种概念了
chenxytw
2018-05-06 16:44:11 +08:00
不过这个概念的完全移除弄了好久。。。。
可以看这个 bug
https://bugs.python.org/issue23702
u2386
2018-05-06 16:50:55 +08:00
@chenxytw 也是项目中的一个“骚操作”让我踩到了🤦‍♂️

虽然不是“通识”,但这个改变毕竟不是简单的语法改变,而是概念上变动,我觉得应该有一个官方的提醒。
变动不比 print 从 statement 变成 function 来的小。
chenxytw
2018-05-06 17:04:48 +08:00
@u2386 可能在他们看来,这个不影响大多数程序的运行吧 Orz
a132811
2018-05-10 18:02:24 +08:00
python3 这样更加清晰了.
@staticmethod 本来就是纯函数,不用 self/cls
@classmethod 是 method, 默认带 cls
A.a 也是纯函数
A().a 才是 method, 默认带 cls, 这里的 cls=A() 其实就是 self

cls 本质就是 metaclass 的实例(实例自己叫自己 self )

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/452551

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX