V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
u2386
V2EX  ›  Python

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

  •  
  •   u2386 · 2018-05-06 16:17:30 +08:00 · 2557 次点击
    这是一个创建于 2183 天前的主题,其中的信息可能已经有所发展或是发生改变。

    以下是通过 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 ” 之类的文章提到。

    6 条回复    2018-05-10 18:02:24 +08:00
    locktionc
        1
    locktionc  
       2018-05-06 16:27:28 +08:00
    你这个发现非常好。
    chenxytw
        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 中已经遗弃了,没有这种概念了
    chenxytw
        3
    chenxytw  
       2018-05-06 16:44:11 +08:00   ❤️ 1
    不过这个概念的完全移除弄了好久。。。。
    可以看这个 bug
    https://bugs.python.org/issue23702
    u2386
        4
    u2386  
    OP
       2018-05-06 16:50:55 +08:00
    @chenxytw 也是项目中的一个“骚操作”让我踩到了🤦‍♂️

    虽然不是“通识”,但这个改变毕竟不是简单的语法改变,而是概念上变动,我觉得应该有一个官方的提醒。
    变动不比 print 从 statement 变成 function 来的小。
    chenxytw
        5
    chenxytw  
       2018-05-06 17:04:48 +08:00
    @u2386 可能在他们看来,这个不影响大多数程序的运行吧 Orz
    a132811
        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 )
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   2930 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 12:42 · PVG 20:42 · LAX 05:42 · JFK 08:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.