gpt4 book ai didi

python - 为什么描述符(在Python中)不能插入(放置)到已经初始化的对象中?

转载 作者:行者123 更新时间:2023-12-01 05:49:05 24 4
gpt4 key购买 nike

在编码过程中,我面临着需要更改对象属性(但不是类属性)的行为。我发现已经初始化的对象无法使用描述符进行修补。那么为什么呢?

代码示例

class A(object):
pass

class D(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
pass
def __get__(self, obj, objtype=None):
return 5

A.x = D()
A.x
Out[12]: 5 # work!
a = A()
a.y = D()
a.y
Out[14]: <__main__.D at 0x13a8d90> # not work!

最佳答案

来自the documentation .

For objects, the machinery is in object.__getattribute__() which transforms b.x into type(b).__dict__['x'].__get__(b, type(b)).

也就是说,实例 (b) 上的属性查找会转换为 (type (b))。描述符在类级别运行。

至于为什么这是真的,这是因为描述符基本上是一种在属性查找上执行类似方法的工作(即调用方法)的方法。方法本质上是类级别的行为:您通常在类上定义所需的方法,并且不会向单个实例添加额外的方法。在实例上进行描述符查找就像在实例上定义方法一样。

现在,可以为实例分配新方法,也可以让描述符在特定类的实例上工作。你只需要做额外的工作。正如上面的文档引用所述,机制位于 object.__getattribute__ 中,因此您可以通过在类上定义自定义 __getattribute__ 来覆盖它:

class Foo(object):
def __getattribute__(self, attr):
myDict = object.__getattribute__(self, '__dict__')
if attr in myDict and hasattr(myDict[attr], '__get__'):
return myDict[attr].__get__(self, type(self))
else:
return super(Foo, self).__getattribute__(attr)

class D(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
pass
def __get__(self, obj, objtype=None):
return 5

然后:

>>> f = Foo()
>>> f.x = D()
>>> f.x
5

因此,如果您觉得有必要这样做,您就可以实现它。这不是默认行为,因为这不是描述符的设计目的。

关于python - 为什么描述符(在Python中)不能插入(放置)到已经初始化的对象中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15061455/

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