Python@property与它返回的字段id相同
为了更好地理解属性,我制作了以下简单片段:Python@property与它返回的字段id相同,python,properties,Python,Properties,为了更好地理解属性,我制作了以下简单片段: class foo: def __init__(self, val): self.val = val @property def val(self): return self._val @val.setter def val(self, value): if value < 0: raise ValueError("Value has to be larger than 0")
class foo:
def __init__(self, val):
self.val = val
@property
def val(self):
return self._val
@val.setter
def val(self, value):
if value < 0:
raise ValueError("Value has to be larger than 0")
else:
self._val = value
f1 = foo(2)
print(id(f1._val) == id(f1.val)) #print true
当我返回指向函数的指针(不确定指针在这个上下文中是否正确?)时,没有任何条件,这是非常明显的。但是在这里,我的第一个代码片段是如何工作的,即使self.\u val
和self.val
是同一个对象
为什么f1._val和f1.val都是同一个对象
因为您正在将它们设置为代码中的同一对象。您获取您的值,在本例中为2
,并将其分配给self.val
和self.\u val
你所做的相当于
a=2
b=2
a==b
True
另外,当类型(f1.val)是函数时,为什么它是int
使用
@属性
装饰器时,该方法不再可调用。您可以将其视为一个属性。在您的示例中,val
是一个描述符,如中所述。使用描述符,对变量的访问被替换为对其\uuuuu get\uuuuu
、\uuuuu set\uuuuuu
和\uuu delete\uuuu
方法的调用。属性
函数是创建描述符的快捷方式。由于“property”和“descriptor”的含义相同,我不知道为什么会使用两个不同的名称
与
val
绑定到一个对象,该对象的\uuu get\uu
执行函数体。它获取局部变量\u val
与
@val.setter
def val(自身,值):
如果值<0:
提升值错误(“值必须大于0”)
其他:
自我价值=价值
绑定到val
的对象将被更新,以便其\uuuuuu设置\uuuuu
执行函数体,设置\u val
当python执行f1.val
时,它会获取由“val”引用的对象,但在返回之前,它会检查该对象是否具有\uuuu get\uuu
。如果是这样,它将调用\uuu get\uu
并使用其返回值,而不是返回对象。在您的情况下,“\u val”返回,因此它们自然是相等的
如果将属性函数更改为获取“val”而不是“_val”,python仍然遵循相同的规则。“val”是一个描述符,因此会调用它的
\uuuu get\uuuu
,它会再次尝试获取“val”,但它是一个描述符。。。“为什么f1.\u val
和f1.val
都是同一个对象?”因为val
属性getter只返回self.\u val
。。。我不确定你不明白的是什么。当您执行f1.val
时,它调用getter并计算为该值,您理解它吗?foo.val
不再是一个函数。它是一个属性
<代码>属性对象实现。基本上,一些类上的描述符,MyClass。一些描述符可以定义一个\uuuu get\uuuu
、\uu set\uuuu
和\uu delete\uuu
方法。创建实例时,myinstance=MyClass()
然后将为myinstance.my_描述符
,myinstance.my_descriptor=foo
,调用描述符\uu get\uuuuuuuuuuuu
,myinstance.my_descriptor=foo
,调用myinstance>myinstance.my_descriptor=foo
,和del myinstance.my_描述符
分别是当类中定义了另一个方法时,例如func
返回int
,我将以非常相同的方式实例化类type(f1.func)
是方法,而type(f1.func())
是int。这对我来说很有意义。那么type(f1.val())
也应该是一个int,而type(f1.val)
应该是我所理解的一个方法(不过我可能错了)*它不是一个方法,而是一个属性
对象。你知道@property
在做什么吗?你知道什么是装饰师吗?我在上面解释了描述符,property
也是一个decorator,但这主要是语法上的suguar。基本上,@property def val(self):…
等同于def val(self):…
然后val=property(val)
。因此类上的val
属性不再是函数/方法。它是一个属性
描述符。注意,函数也是描述符,这就是它们“神奇地”提供实例作为第一个参数的方式是的,是的,谢谢。我的评论是在网页刷新之前发布的,我看到了你的第二条评论。
RecursionError: maximum recursion depth exceeded in comparison
@property
def val(self):
return self._val
@val.setter
def val(self, value):
if value < 0:
raise ValueError("Value has to be larger than 0")
else:
self._val = value