class P:
def __init__(self,x):
self.x = x
@property
def x(self):
return self.__x
@x.setter
def x(self, x):
if x < 0:
self.__x = 0
elif x > 1000:
self.__x = 1000
else:
self.__x = x
我正在努力学习&#39; getters&#39;和&#39;塞特斯&#39;方法。 当我使用这些输入创建实例时:
p1 = P(1001)
print(p1.x)
p1.x = -12
print(p1.x)
我得到了输出:
1001
-12
我不知道为什么我会1001
和-12
而不是1000
和0
。
答案 0 :(得分:8)
你真正的问题是你正在使用Python 2.x和旧式的类。您显示的代码将按预期在Python 3.x上运行(当然,除了损坏的缩进除外)。如果通过显式继承P
使object
成为新式类(例如,将其声明为class P(object):
),它也适用于Python 2.x.
在旧式类中,问题是你的setter和getter方法都被命名为x
,并且两者都在竞争同一命名空间中的条目。
如果您有以下代码:
@x.setter
def x(self, x):
...
使用您指定的代码创建一个新的函数对象(容易引起混淆,名为x
),然后调用x.setter(x_function_object)
,并返回x.setter
返回的任何内容(这将是将__get__
和__set__
定义的描述符对象分配给命名空间字典中的x
,该字典传递给元类的__new__
方法并用于构建类的类型。< / p>
但是,在旧式类中,当您编写self.x = ...
时,它将直接调用__setattr__
而不是使用描述符协议(self.__dict__['x'].__set__(x, ...)
)。因此,self.x
方法中对__init__
的分配将覆盖setter方法而不是调用它。