Python中的属性

sha*_*awn 7 python

什么是使用变量self._age的原因?一个类似的名称,它没有链接到已经使用过的self.age?

class newprops(object):
    def getage(self):
        return 40
    def setage(self, value):
        self._age = value
    age = property(getage, setage, None, None)
Run Code Online (Sandbox Code Playgroud)

ken*_*ytm 11

self.age已被属性占用,您需要为实际变量赋予另一个名称,即_age此处.

顺便说一句,从Python 2.6开始,你可以用装饰器来编写:

def newprops(object):

    @property
    def age(self):
        return 40

    @age.setter
    def age(self, value):
        self._age = value
Run Code Online (Sandbox Code Playgroud)

  • 使用以下划线开头的名称还有另一个优点:它是"私人"(="除非你必须接触")公认的命名约定. (3认同)

Esc*_*alo 6

一些面向对象的语言具有所谓的私有属性,这些属性不能从类方法之外访问.这很重要,因为某些属性并不是要直接更改,而是要根据其他内容进行更改,或者在更改之前进行验证.在Python中你没有私有属性,但你可以通过使用getter和setter来实现类似的东西,这个变量以下划线开头--Python的私有方法和属性约定.

例如.矩形三角形的斜边是由h=sqrt(a*a+b*b),因此您不能h直接更改,因为关系必须保持.另外,假设一个名字必须是我的格式LASTNAME COMMA FIRSTNAME,那么你必须在分配之前验证是这种情况self.lastname.

属性getter允许你获得斜边,但禁止你设置它.属性设置器允许您设置属性,但您可以在实际设置属性之前进行检查.

所以:

class Person(object)
 def __init__(self):
  # The actual attribute is _name
  self._name = None
 @property
 def name(self):
  # when I ask for the name, I mean to get _name
  return self._name
 @name.setter
 def name(self, value):
  # before setting name I can ensure that it has the right format
  if regex_name.match(value):
   # assume you have a regular expression to check for the name
   self._name = value
  else:
   raise ValueError('invalid name')
Run Code Online (Sandbox Code Playgroud)

另一个例子:

class Triangle(object):
 def __init__(self, a, b):
  # here a and b do not need to be private because
  # we can change them at will. However, you could
  # make them private and ensure that they are floats
  # when they are changed
  self.a = a 
  self.b = b
 @property
 def h(self):
  return math.sqrt(a*a+b*b)
 # notice there is no h.setter - you cannot set h directly
Run Code Online (Sandbox Code Playgroud)

  • 很好的例子,有效的评论. (2认同)