gpt4 book ai didi

python - 使用 __set__ 获得类级别类型描述符的方法

转载 作者:太空宇宙 更新时间:2023-11-03 14:20:40 24 4
gpt4 key购买 nike

我的数据描述符适用于同时具有 __set____get__ 的对象。

但是,类描述符似乎不支持 __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

哪些输出

Object
__get__
__set__
Class
__get__

如您所见,类级别 __set__ 没有被调用。

是否有一些解决方法或 hack(无论多么可怕)允许类上的 __set__ 数据描述符?

需要说明的是,我不希望调用代码必须实现任何“hack”。我希望调用代码按上面的预期工作,但任何 hack 都在“幕后”。

使用 Python 2.7

最佳答案

我不会详细介绍整个 Descriptor 协议(protocol)。我自己并不完全理解;事实上,您已经提醒我,我需要停止懒惰,真正投入其中。同时,我会这样说:

的理解是,描述符只会在实例上发挥它们的魔力。现在,您可能已经知道这一点,这就是为什么您想知道是否有破解方法可以绕过此限制。

如果您稍微熟悉元类,就会知道类也是实例。类可以是类的实例,类也可以是实例等等。这很棒,因为您要问的内容看起来像这样:

class Descriptor(object):
def __get__(self, obj, cls):
print('__get__')
def __set__(self, obj, value):
print('__set__')

class MetaClass(type):
descriptor = Descriptor()

class Class(object):
__metaclass__ = MetaClass

# This will work fine when you do Class.descriptor, as you asked
# but it will raise an AttributeError if you do
# a = Class()
# a.descriptor
# Read on for the full explanation...

MetaClass 中定义的descriptor 变量只对Class 类可见。任何试图调用它的 Class 实例都会给您一个 AttributeError。这是因为类的实例在搜索属性时,先搜索自己的__dict__再搜索类的__dict__,但不会搜索到类的 >__元类__。现在,如果您想同时使用它并为类及其实例使用相同的变量名(尽管我不推荐它,因为它会引起混淆),您可以这样做:

class Descriptor(object):
def __get__(self, obj, cls):
print('__get__')
def __set__(self, obj, value):
print('__set__')

class MetaClass(type):
descriptor = Descriptor()

class Class(object):
__metaclass__ = MetaClass
descriptor = Descriptor()

此时你可能想知道:如果一个实例在搜索它的类之前搜索它自己的 __dict__,那它是如何调用“Class.descriptor”的如果 Class.descriptor 本质上是它的,则不会选择 'a.descriptor' 使用的相同描述符(正如您所观察到的,它不会正常工作)自己的实例变量(来自元类 POV)

答案是数据描述符(定义了 __get____set__ 的描述符),而不是非数据描述符(只定义了 __get__ ), 优先于实例变量。换句话说,MetaClass 中的 descriptor 变量是 Class 将选取的变量,因为它优先于 Class自己的 descriptor 变量。 Class 实例也是如此,它会自动获取 Class 中定义的 descriptor 变量。

希望我没有让您感到困惑。这些东西很容易忘记,我认为更是如此,因为大多数时候了解这种魔法水平不是很常见也没有必要。我不得不刷新我对这个的内存!好问题:)

关于python - 使用 __set__ 获得类级别类型描述符的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28403069/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com