gpt4 book ai didi

python - 为什么 instance.attribute = value 可以工作,而 __set__ 方法没有在属性中实现?

转载 作者:行者123 更新时间:2023-11-28 18:38:22 25 4
gpt4 key购买 nike

我正在通过属性来研究描述符协议(protocol),我正在这样写我自己的属性:

class my_property(object):
def __init__(self, fget=None, fset=None, fdel=None, doc=None):
self.fget = fget
self.fset = fset
self.fdel = fdel
if doc is None and fget is not None:
doc = fget.__doc__
self.__doc__ = doc
def __get__(self, obj, objtype=None):
if obj is None:
return self
if self.fget is None:
raise AttributeError("unreadable attribute")
return self.fget(obj)

def setter(self, fset):
return type(self)(self.fget, fset, self.fdel)

class test_my_property(object):
def __init__(self, value):
self._val = value

@my_property
def val(self):
return self._val

@val.setter
def val(self, value):
self._val = value

def main():
c = test_my_property(5)
print c.val
c.val = 10
print c.val
print type(c).__dict__['val'].__set__

然后我得到:

5
10
AttributeError: 'my_property' object has no attribute '__set__'

我的问题是,既然“__set__”没有定义,那么“c.val = 10”如何工作?如果"__set__"是my_property从object继承的,那么,为什么会报AttributeError呢?

最佳答案

__set__ 不是继承自对象。获取和设置 val 属性之所以有效,是因为在访问对象的属性时,首先会检查实例,然后检查类。由于您设置了实例属性 val,它会使用它。如果您正在查看一个没有描述符的简单示例,我认为这一点尤其明显,

>>> class Foo(object):
... val = 5
...
>>> f = Foo()
>>> f.val # f doesn't have val so fallback on Foo
5
>>> f.val = 10
>>> f.val # f now has val so use it
10
>>> del f.val # oops what now
>>> f.val # class again
5

上面的例子和你的唯一区别是你的类 val 是(当你完成时)一个属性。

综上所述,您通常不希望将您的属性命名为与将保存其内容的实例属性相同的名称。通常的公式是这样的,

class Foo(object):
def __init__(self, value):
self._val = value

@property
def val(self):
return self._val

关于python - 为什么 instance.attribute = value 可以工作,而 __set__ 方法没有在属性中实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30091273/

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