我不清楚@property
的使用(优点和缺点)。我想询问一些使用在 Martijn 的帮助下构建的类的示例.
数据(文本格式)始终具有 x
、y
和 z
来表征点(1、2 和3 列文本文件)。有时我有一个“classification
”(第四列)属性和/或 location
(第五列)。取决于文件的处理方式(有时更多属性)。
class Point(object):
__slots__= ("x", "y", "z", "data", "_classification")
def __init__(self, x, y, z):
self.x = float(x)
self.y = float(y)
self.z = float(z)
self.data = [self.x,self.y,self.z]
@property
def classification(self):
return getattr(self, '_classification', None)
@classification.setter
def classification(self, value):
self._classification = value
if value:
self.data = self.data[:3] + [value]
else:
self.data = self.data[:3]
def __len__(self):
return len(self.data)
p = Point(10,20,30)
len(p)
3
p.classification = 1
len(p)
4
p.data
[10.0, 20.0, 30.0, 1]
我希望在已设置分类
时添加位置
,以便理解使用@property
的原理。我尝试使用以下代码,但我不知道这是否是Pythonic:
class Point(object):
__slots__= ("x", "y", "z", "data", "_classification",'_location')
def __init__(self, x, y, z):
self.x = float(x)
self.y = float(y)
self.z = float(z)
self.data = [self.x,self.y,self.z]
@property
def classification(self):
return getattr(self, '_classification', None)
@classification.setter
def classification(self, value):
self._classification = value
if value:
self.data = self.data[:3] + [value]
else:
self.data = self.data[:3]
@property
def location(self):
return getattr(self, '_location', None)
@location.setter
def location(self, value):
self._location = value
if value:
self.data = self.data[:4] + [value]
else:
self.data = self.data[:4]
def __len__(self):
return len(self.data)
p = Point(10,20,30)
p.classification = 1
p.data
[10.0, 20.0, 30.0, 1]
p.location = 100
p.data
[10.0, 20.0, 30.0, 1, 100]
p = Point(10,20,30)
p.location = 100
p.data
[10.0, 20.0, 30.0, 100]
最佳答案
所以,你的类有效,你只是问它是否是 Pythonic 的。我不是专家,但我会推荐您引用Zen of Python :
Explicit is better than implicit.
对我来说,当您设置一个属性(位置、分类)时,它最终会默默地修改其他属性,这是隐式的,而不是显式的。我认为更好、更容易理解的用例是使用诸如 assign_location
和/或 assign_classification
方法。这样,使用 API 的人就可以知道他不仅仅是在设置属性,而是在调用一个函数,该函数具有解释其作用的文档字符串。
至于该属性的哲学是什么,我不确定它的包含是否基于哲学。属性装饰者所做的就是去掉这样难看的东西:
class Foo:
def __getattr__(self, attr):
if attr == 'location':
...
elif attr == 'classification':
...
我非常喜欢的一个用途是使用属性来保证线程安全。例如:
class Foo(object):
def __init__(self):
self.lock = threading.Lock()
@property
def classification(self):
return self.classification
@classification.setter
def classification(self, value):
with self.lock:
(something else thread-protected)
self.classification = value
最后,还有一个建议。除非您知道为什么使用插槽,否则不要这样做。除非您知道为什么需要插槽,否则您不需要它们。
关于python - 在Python中使用@property构建一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15138451/