Python 从类本身内部引用属性
假设我有一门课看起来像Python 从类本身内部引用属性,python,Python,假设我有一门课看起来像 class MeasurementList: def __init__(self, measurement_list): self.__measurements = measurement_list @property def measurements(self): return self.__measurements 从类内部检索self.measures的值的最具python风格的方法是什么;直接访问变量还是通过属性访问(外部访问器)
class MeasurementList:
def __init__(self, measurement_list):
self.__measurements = measurement_list
@property
def measurements(self):
return self.__measurements
从类内部检索self.measures
的值的最具python风格的方法是什么;直接访问变量还是通过属性访问(外部访问器)?即
或
是否有任何替代方案具有速度优势,或更容易重构,或其他因素?我想您已经看到类似这样的代码是Java。然而,在属性访问完全满足目的的情况下,使用方法是非常不和谐的。您现有的代码将更简单地编写为 类别度量列表:
def __init__(self, measurement_list):
self.measurements = measurement_list
那么就不需要属性了
这一点大概是为了避免类外部的代码改变
\u measurements
属性的值。这在实践中有多大必要?我想您已经看到过类似于Java的代码。然而,在属性访问完全满足目的的情况下,使用方法是非常不和谐的。您现有的代码将更简单地编写为
类别度量列表:
def __init__(self, measurement_list):
self.measurements = measurement_list
那么就不需要属性了
这一点大概是为了避免类外部的代码改变
\u measurements
属性的值。这在实践中有多大必要?在课堂内外使用setter和getter。在setter和getter中添加一些额外的数据处理后,您的代码将更易于维护:
class C(object):
_p = 1
@property
def p(self):
print 'getter'
return self._p
@p.setter
def p(self, val):
print 'setter'
self._p = val
def any_method(self):
self.p = 5
print '----'
a = self.p
myObject = C()
myObject.any_method()
从输出中,可以看到setter和getter被调用:
setter
----
getter
在课堂内外同时使用setter和getter。在setter和getter中添加一些额外的数据处理后,您的代码将更易于维护:
class C(object):
_p = 1
@property
def p(self):
print 'getter'
return self._p
@p.setter
def p(self, val):
print 'setter'
self._p = val
def any_method(self):
self.p = 5
print '----'
a = self.p
myObject = C()
myObject.any_method()
从输出中,可以看到setter和getter被调用:
setter
----
getter
属性的要点是在获取/设置字段的过程中添加额外的功能,同时保留字段的接口 这意味着您从一个简单字段开始,并将其作为字段访问:
class MeasurementList:
def __init__(self, measurement_list):
self.measurements = measurement_list
def foo(self):
print("there are %d measurements" % len(self.measurements))
然后,如果您想要/必须向setter/getter添加额外的逻辑,则可以将其转换为属性,而不必更改接口。因此,无需重构访问代码
class MeasurementList:
def __init__(self, measurement_list):
self._count = 0
self.measurements = measurement_list
@property
def measurements(self):
return self._measurements
@measurements.setter
def measurements(self value):
self._measurements = value
self._count = len(value)
def foo(self):
print("there are %d measurements" % (self._count))
def bar(self):
print(self.measurements)
使用属性的其他原因是只读属性或返回计算(不直接存储在字段中)值的属性。在只读属性的情况下,您可以直接访问backing字段进行写入(从类内部)
记住所有这些,您不应该忘记python中没有“private”这样的东西。如果有人真的想访问私人文件,他可以这样做。按照惯例,任何以下划线开头的内容都应该被视为私有的,并且调用方不能访问。这也是为什么一个下划线就足够了。两个下划线启动一些名称损坏,主要用于避免名称冲突,而不是禁止访问。属性的要点是在获取/设置字段的过程中添加附加功能,同时保留字段的接口 这意味着您从一个简单字段开始,并将其作为字段访问:
class MeasurementList:
def __init__(self, measurement_list):
self.measurements = measurement_list
def foo(self):
print("there are %d measurements" % len(self.measurements))
然后,如果您想要/必须向setter/getter添加额外的逻辑,则可以将其转换为属性,而不必更改接口。因此,无需重构访问代码
class MeasurementList:
def __init__(self, measurement_list):
self._count = 0
self.measurements = measurement_list
@property
def measurements(self):
return self._measurements
@measurements.setter
def measurements(self value):
self._measurements = value
self._count = len(value)
def foo(self):
print("there are %d measurements" % (self._count))
def bar(self):
print(self.measurements)
使用属性的其他原因是只读属性或返回计算(不直接存储在字段中)值的属性。在只读属性的情况下,您可以直接访问backing字段进行写入(从类内部)
记住所有这些,您不应该忘记python中没有“private”这样的东西。如果有人真的想访问私人文件,他可以这样做。按照惯例,任何以下划线开头的内容都应该被视为私有的,并且调用方不能访问。这也是为什么一个下划线就足够了。两个下划线会引起一些名称混乱,这主要是为了避免名称冲突,而不是禁止访问。在Python中使用属性时,除非有必要,否则几乎应该始终避免访问属性下的属性。为什么? Python中的属性用于创建getter、setter和deleter,但您可能知道它。 在这些操作过程中处理属性数据时,通常会使用它们。我现在还没有一个很好的例子,但是考虑如下:
class User:
# _password stores hash object from user's password.
@property
def password(self):
return self._password.hexdigest() # Returns hash as string
@password.setter
def password(self, val):
self._password = hash(val) # Creates hash object
这里使用\u password
和password
会产生完全不同的输出。在大多数情况下,您只需要密码
,包括类定义内部和外部,除非您希望直接与它包装的对象交互
如果您在getter和attribute中返回了相同的对象,那么您应该遵循相同的实践,因为您可能希望sameday向其添加一些检查或机制,这将避免您每次使用\u attribute
时都进行重构,在创建更复杂的描述符时,遵循该约定也可以避免出现错误
另外,在代码中,请注意使用
\uu measurements
(前导双下划线)会导致属性名的名称混乱,因此如果您从MeasurementList
继承,您几乎无法访问此属性。在Python中使用属性时,除非有必要,否则几乎应该始终避免访问属性下的属性。为什么?
Python中的属性用于创建getter、setter和deleter,但您可能知道它。
在这些操作过程中处理属性数据时,通常会使用它们。我现在还没有一个很好的例子,但是考虑如下:
class User:
# _password stores hash object from user's password.
@property
def password(self):
return self._password.hexdigest() # Returns hash as string
@password.setter
def password(self, val):
self._password = hash(val) # Creates hash object
这里使用\u password
和password
会产生完全不同的输出。在大多数情况下,您只需要密码
,包括类定义的内部和外部