我的数据描述符同时适用于__set__
和{
然而,类描述符似乎不支持__set__
。这样做反而会用指定的值替换描述符对象本身。在
下面的代码演示了这一点
from __future__ import print_function
class Descriptor(object):
def __get__(self, obj, cls):
print('__get__')
def __set__(self, obj, value):
print('__set__')
class Class(object):
descriptor = Descriptor()
print('Object')
a = Class()
a.descriptor
a.descriptor = 1
print('Class')
Class.descriptor
Class.descriptor = 2
哪些输出
^{pr2}$如您所见,类级别__set__
没有被调用。在
是否有一些解决方法或黑客(无论多么可怕)允许在类上使用__set__
数据描述符?在
我只是想说清楚,我不想调用代码必须实现任何“黑客”。我希望调用代码能像上面预期的那样工作,但是任何黑客行为都是“幕后黑手”。在
使用Python2.7
我不想讨论整个描述符协议。我自己并没有完全理解这一点;事实上,你提醒了我,我需要停止懒惰,并投入其中。同时,我要说:
我所理解的是,描述符只会在实例上发挥其魔力。现在,你可能已经知道了,这就是为什么你想知道是否有黑客可以绕过这个限制。在
如果您对元类稍有了解,您就会知道类也是实例。类可以是类的实例,也可以是实例等等。这很好,因为你的要求看起来像这样:
在
^{pr2}$MetaClass
中定义的descriptor
变量仅对Class
类可见。任何试图调用Class
的实例都将给您一个AttributeError
。这是因为类的实例在搜索属性时,在搜索类的__dict__
之前先搜索它们自己的__dict__
,但它不会搜索到类的__metaclass__
。现在,如果你想同时拥有它,并且对类和它的实例使用相同的变量名(尽管我不推荐它,因为它会引起混淆),那么可以这样做:此时您可能会想知道:如果一个实例在搜索它的类之前搜索它自己的
__dict__
,那么如果Class.descriptor
本质上是它自己的实例变量(来自元类POV),那么调用“Class.descriptor
”怎么会不会选择“Class.descriptor
”使用的相同描述符(正如您所观察到的那样,这将无法正常工作)?在答案是数据描述符(同时定义了}的描述符)与非数据描述符(只定义了
__get__
和{__get__
)相比,其优先级高于实例变量。换句话说,MetaClass
中的descriptor
变量是Class
将选择的变量,因为它优先于Class
自己的descriptor
变量。Class
实例也是如此,它自动获取在Class
中定义的descriptor
变量。在我希望我没有把你弄糊涂。这些东西很容易被遗忘,我认为更是如此,因为它不是很常见,也没有必要了解这种水平的魔术大多数时间。我不得不在这件事上刷新我的记忆!好问题:)
相关问题 更多 >
编程相关推荐