Python描述符不适用于Python 2.7

Dav*_*ter 5 python compatibility python-2.7 python-3.x

此代码在Python 2和中生成不同的输出Python 3.

class Descriptor(object):
    def __get__(self, instance, owner):
        print('read')
        return 1

    def __set__(self, instance, value):
        print('write')

    def __delete__(self, instance):
        print('del')

class C():
    a = Descriptor()

c = C()                                
c.a                                    
c.a = 3
del c.a
c.a

print('finished')
Run Code Online (Sandbox Code Playgroud)

Python 2的输出是:

read
read
finished
Run Code Online (Sandbox Code Playgroud)

对于Python 3,它是:

read
write
del
read
finished
Run Code Online (Sandbox Code Playgroud)

为什么这样工作?如何Python 2描述不同Python 3的描述?

这也没有意义,因为http://docs.python.org/release/3.0.1/reference/datamodel.html#invoking-descriptors清楚地描述了与http://docs.python.org/reference/完全相同的内容. datamodel.html#调用描述符

(这些是Python 2.7Python 3.0.的文件.)

agf*_*agf 5

编辑:正如Ned Deily在评论中准确指出的,发生这种情况的原因是你的类C是Python 2上的旧式类,因为你没有指定object或另一个新式类作为它的基类.


因为在Python 2上,c.a当您执行c.a = 3隐藏描述符对象时,您将创建一个新的实例属性C.a.

c = C()
c.a
c.a = 3
print c.__dict__['a']
print C.__dict__['a']
del c.a
c.a
Run Code Online (Sandbox Code Playgroud)

得到:

read
3
<__main__.Descriptor object at 0x04625570>
read
finished
Run Code Online (Sandbox Code Playgroud)

  • 您的C类是Python 2中的旧式类.将其更改为"C类(对象)",Py 2与Py 3的工作方式相同. (9认同)