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
会产生完全不同的输出。在大多数情况下,您只需要
密码
,包括类定义的内部和外部