【发布时间】:2017-07-30 00:42:16
【问题描述】:
我很好奇 Python 3 中的 @property 注释。
我知道我可以在调用这样的属性之间操纵状态...
class Obj:
_x = 0
@property
def x(self):
self._x += 1
return self._x
obj = Obj()
print(obj.x)
print(obj.x)
... 打印:
1
2
但是,这种机制在传递给函数后是否可以保留?
取如下函数:
def f(x):
print(x)
print(x)
假设我们无法更改它,这意味着我们不能简单地将对象传递给函数并直接使用属性。是否可以只传递属性或类似的东西,这样每次x 在函数x 中“使用”时都会增加?有没有办法通过操纵和传递类或对象本身来做到这一点?类似于__call__(self, ...) 的东西,或者将@property 添加到类本身或类的__init__(self, ...) 中?
我尝试了以下幼稚的方法...
obj = Obj()
f(obj.x)
...和...
obj = Obj()
f(getattr(obj, 'x'))
都打印...
1
1
... 这是有意义的,因为它在传递给f 之前被评估。我也尝试扩展Obj:
class Obj:
_x = 0
@property
def x(self):
self._x += 1
return self._x
def y(self):
return x
...然后去...
obj = Obj()
f(obj.y)
...但它会产生...
<bound method Obj.y of <__main__.Obj object at 0x000002379E015748>>
<bound method Obj.y of <__main__.Obj object at 0x000002379E015748>>
这也很有意义,因为我们只是获取方法本身并将其传递给f 函数。
请注意:这不是现实世界的问题/示例。我只是想了解python本身的原理和局限性。
【问题讨论】:
-
属性为descriptors。注意,实际发生的是当你访问
obj.x时,本质上是Obj.x.__get__(obj, Obj) -
每当我们在上面的装饰器类中分配或检索像
x这样的任何对象属性时,Python 都会在对象的 dict 字典中搜索它。尝试obj.__dict__自己查看,它会返回{'_x': 3}。同样type(obj.x)将返回int,而不是method。
标签: python python-3.x properties