我最近发现了Python的property内置函数,它将类方法getter和setter伪装成类的属性.我现在很想以我认为不合适的方式使用它.
property如果类A具有_x您想要限制的允许值的属性,那么使用关键字显然是正确的做法; 即,它将取代用C++编写的构造getX()和setX()构造.
但是在哪里将函数作为属性是合适的呢?例如,如果你有
class Vertex(object):
def __init__(self):
self.x = 0.0
self.y = 1.0
class Polygon(object):
def __init__(self, list_of_vertices):
self.vertices = list_of_vertices
def get_vertex_positions(self):
return zip( *( (v.x,v.y) for v in self.vertices ) )
Run Code Online (Sandbox Code Playgroud)
是否适合添加
vertex_positions = property( get_vertex_positions )
Run Code Online (Sandbox Code Playgroud)
?
让发电机看起来像财产一样可以吗?想象一下,如果我们的代码中的更改意味着我们不再Polygon.vertices以相同的方式存储.那么添加它可以Polygon吗?
@property
def vertices(self):
for v in self._new_v_thing:
yield v.calculate_equivalent_vertex()
Run Code Online (Sandbox Code Playgroud)
Mik*_*ham 14
如果您具有普通属性并且获取和/或设置它对于类的用户有意义,则直接公开该属性.公共成员在某些语言中诅咒的一个重要原因是,如果您以后需要做一些更复杂的事情,那么您需要进行API更改; 在Python中,您可以定义一个属性.
如果您正在使用某些内容,则应将其抽象为属性访问,请使用property.如果你想让外部状态(你的情节或网站或其他东西)意识到这种变化,或者如果你要包装一些直接使用成员的库,那么属性可能就是你想要的.
如果某些东西不是属性-y,请不要将其作为属性.制作方法没有坏处,它可能是有利的:它的作用更明显,如果需要,可以传递一些绑定方法,可以在不更改API的情况下添加关键字参数.
我很难想象我会将生成器函数用作属性的情况.拥有一个行为相似的普通属性的唯一方法需要相当多的复杂性,因此这种情况不会让人联想到属性访问.
您指出可以property用来限制对某些内部属性的访问_x.这可能是真的,但请记住
如果您要执行诸如清理输入以确保安全性或重要事项,那么显式优于隐式.当你遇到这样的事情时,你不希望感觉代码只是工作,因为那样你就会遇到没有的代码.
有时人们会使用它property来实现只读属性.通常更好的方法是拥有一个普通的属性,并意识到你无法阻止用户做一些愚蠢和不受支持的事情.
挑剔你可能会觉得有趣:
property不是关键字; 这是你可以重新绑定的正常名称.这很有意思,因为property它不是语法或任何东西:它是一个普通的类,你可以用纯Python实现自己.它使用相同的机制使方法在Python 描述符中起作用.
你描述了什么property是"伪装类方法getter和setter",但事实并非如此.所property采取的只是正常的功能,根本不需要在你的班级中定义; property会self为你而过.在Python中查找它们时,函数实际上不会成为方法,而是Python在运行时创建方法对象.在类定义期间,它们只是函数.当你有一个普通的方法时,它被称为"实例方法"; 在Python中,"类方法"指的是另一种特殊的东西,它类似于属性,可以改变查找属性时发生的情况.