Python 2.7中Python描述符不起作用

5
这段代码在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')

Python 2的输出如下:
read
read
finished

对于 Python 3,它是:

read
write
del
read
finished

为什么会这样工作?Python 2描述符与Python 3描述符有何不同?
这也没有意义,因为http://docs.python.org/release/3.0.1/reference/datamodel.html#invoking-descriptors清楚地描述了与http://docs.python.org/reference/datamodel.html#invoking-descriptors完全相同的内容。
(这些是Python 2.7Python 3.0的文档。)

(顺便说一句,Python 3.0及其文档已经过时并退役,请勿使用Python 3.0或3.0.1。当前文档位于http://docs.python.org/py3k/,当前版本为3.2.3。) - Ned Deily
1个回答

5

编辑: 正如Ned Deily在评论中准确指出的那样,原因是你的类C在Python 2中是旧式类,因为你没有指定object或另一个新式类作为它的基类。


因为在Python 2上,当你执行c.a = 3时,你正在创建一个新的实例属性c.a,它隐藏了位于C.a处的描述符对象。

c = C()
c.a
c.a = 3
print c.__dict__['a']
print C.__dict__['a']
del c.a
c.a

提供:

read
3
<__main__.Descriptor object at 0x04625570>
read
finished

1
但这意味着我不能在Python 2中使用__set__描述符。为什么Python 3中会有所不同? - Dave Halter
9
你的C类是Python 2中的旧式类。将其改为Class C(object),Py 2就能像Py 3一样使用。 - Ned Deily
该死!很抱歉发了这个问题。 :-) 我将“Descriptor”更改为新样式类,但没有注意到“C”不是新样式类。谢谢Ned。 - Dave Halter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接