以下是通过 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 ” 之类的文章提到。
1
locktionc 2018-05-06 16:27:28 +08:00
你这个发现非常好。
|
2
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 中已经遗弃了,没有这种概念了 |
3
chenxytw 2018-05-06 16:44:11 +08:00 1
|
4
u2386 OP @chenxytw 也是项目中的一个“骚操作”让我踩到了🤦♂️
虽然不是“通识”,但这个改变毕竟不是简单的语法改变,而是概念上变动,我觉得应该有一个官方的提醒。 变动不比 print 从 statement 变成 function 来的小。 |
6
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 ) |