Python - @property和__init __()中的设置之间的区别是什么?

时间:2017-04-06 21:05:27

标签: python properties

无法从这个问题的其他主题得到直接答案:

在Python中,使用

之间的主要区别是什么
class Foo(object):
  def __init__(self, x):
    self.x = x

class Foo(object):
  def __init__(self, x):
    self._x = x

  @property
  def x(self):
    return self._x

通过这种方式使用@property看起来让x只读...但也许有人有更好的答案?谢谢/弗雷德

3 个答案:

答案 0 :(得分:4)

对于您的示例,是的,这允许您具有只读属性。此外,属性可以让您看起来拥有比实际更多的属性。考虑使用.radius.area的圈子。该区域可以根据半径计算,而不必同时存储

import math

class Circle(object):
    def __init__(self, radius):
        self.radius = radius

    @property
    def area(self):
        return math.pi * (self.radius ** 2)

答案 1 :(得分:4)

property装饰器实现使用descriptor protocol,这是我们在Python OOP中进行数据封装的方式。描述符是:

  

通常,描述符是具有“绑定”的对象属性   行为“,其属性访问权已被方法覆盖   在描述符协议中。这些方法是__get__()__set__(),   和__delete__()。如果为对象定义了任何这些方法,   它被称为描述符。

通常,在其他OOP语言中,您使用getter和setter。您经常会看到人们来自Java编写类似这样的Python类:

class A(object):
    def __init__(self, x, y):
        self._x = x
        self._y = y
    def getX(self):
        return self._x
    def getY(self):
        return self._y
    def setX(self, x):
        self._x = x
    def setY(self, y):
        self._y = y
    def some_method_that_uses_attributes(self):
        return self.getX() + self.getY()

这非常你将如何用Python做事。 getter和setter的要点是提供数据封装。我们通过将其包装在getter和setter中来封装对数据属性的访问。然后,如果我们想要添加一些东西,比如说,确保x永远不会设置为低于10的值(作为一个人为的例子),我们只需改变setX的实现方式,我们就不要我们不得不修改其余的代码。但是,在Python中,我们将按如下方式编写上述类:

class A(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def some_method_that_uses_attributes(self):
        return self.x + self.y

来自爪哇的人可能会惊恐地退缩:“你没有正确地封装你的课程!这将成为维护的噩梦!”

不,因为我们有描述符/属性:

class A(object):
    def __init__(self, x, y):
        self._x = x
        self.y = y
    @property
    def x(self):
        return self._x
    @x.setter
    def x(self, val):
        if val > 10:
            self._x = val
        else:
            raise ValueError("x must be greater than 10")
    def some_method_that_uses_attributes(self):
        return self.x + self.y

现在,我们不必折射使用self.x的每种方法,例如some_method_that_uses_attributes。这很好,因为它让我们避免编写一堆样板代码,并且在我们需要它的情况下,实现描述符相对比较直接。此外,这使得我们的代码非常漂亮,代码中没有self.get_this()self.set_that(3),且可读性更高self.thisself.that = 3

答案 2 :(得分:-1)

查看关于Python属性的这篇SO帖子 - 它具体指的是getter / setter,但答案分解了很多关于它们的内容,我相信你想知道的一切都在那里:Python @property versus getters and setters