从类本身内部引用属性

God*_*ith 3 python

假设我有一堂课看起来像

class MeasurementList:

  def __init__(self, measurement_list):
    self.__measurements = measurement_list

  @property
  def measurements(self):
    return self.__measurements
Run Code Online (Sandbox Code Playgroud)

self.measurements从类内部检索值的最Pythonic方法是什么?直接访问变量还是通过属性(外部访问器)?IE,

def do_something(self)
  # do something
  return self.measurements
Run Code Online (Sandbox Code Playgroud)

或者

def do_something(self)
  # do something
  return self.__measurements
Run Code Online (Sandbox Code Playgroud)

任何替代方案是否具有任何速度优势,或更容易重构,或其他因素?

Pet*_*erE 6

属性的要点是向获取/设置字段的过程添加附加功能,同时保留字段的接口。

这意味着您从一个简单的字段开始,并将其作为字段访问:

class MeasurementList:

  def __init__(self, measurement_list):
    self.measurements = measurement_list


  def foo(self):
     print("there are %d measurements" % len(self.measurements))
Run Code Online (Sandbox Code Playgroud)

然后,如果您想要/必须向 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)
Run Code Online (Sandbox Code Playgroud)

使用属性的其他原因是只读属性或返回计算值(不直接存储在字段中)的属性。在只读属性的情况下,您可以直接访问支持字段以进行写入(从类内部)。

class MeasurementList:

  def __init__(self, measurement_list):
    self._measurements = measurement_list

  # readonly
  @property
  def measurements(self):
    return self._measurements

  # computed property
  @property
  def count(self):
    return len(self.measurements)

  def foo(self):
    print("there are %d measurements" % (self.count))

  def bar(self):
    print(self.measurements)
Run Code Online (Sandbox Code Playgroud)

记住所有这些,你不应该忘记 python 中没有“私有”这样的东西。如果有人真的想访问私人的任何东西,他都可以这样做。按照惯例,任何以下划线开头的内容都应被视为私有,并且调用者不能访问。这也是为什么一个下划线就足够的原因。两个下划线启动一些名称修改,主要用于避免名称冲突,而不是禁止访问。