在Python中,属性是否只能通过方法访问?

huangapple go评论87阅读模式
英文:

In python, should attributes only be accessed by methods?

问题

这里有两个处理它们的属性方式不同的类的示例。

class MyClassA():
    def __init__(self):
        self.my_attribute = 1

class MyClassB():
    def __init__(self):
        self._my_attribute = 1

    def get_my_attribute(self):
        return self._my_attribute

    def set_my_attribute(self, value):
        self._my_attribute = value

关于哪种是最佳实践,Python 中并没有一致的共识。

英文:

Here are two examples of classes that handle their attribute differently.

class MyClassA():
    def __init__(self):
        self.my_attribute = 1

class MyClassB():
    def __init__(self):
        self._my_attribute = 1

    def get_my_attribute(self):
        return self._my_attribute

    def set_my_attribute(self, value):
        self._my_attribute = value

Is there a python consensus on which is best practice?

答案1

得分: 1

最佳实践是选择满足您需求的方法。如果您希望其他人在使用您的类时使用getter和setter - 例如进行检查或处理必需的副作用 - 那就是您应该做的。如果只是一个属性,您愿意让其他代码更改它(没有副作用),第一个解决方案就可以了。请注意,还有 @property 装饰器用于更好地完成第二种类型 - 这会比使用 get_...set_... 方法更符合最佳实践:

class MyClassB():
    def __init__(self):
        self._my_attribute = 1

    @property
    def my_attribute(self):
        return self._my_attribute

    @my_attribute.setter
    def my_attribute(self, value):
        self._my_attribute = value

请注意,添加 _ 实际上并不隐藏属性,它只会在尊重它的编辑器中生成警告:

b = MyClassB()
print(b.my_attribute)
b.my_attribute = 10
print(b.my_attribute)
print(b._my_attribute)  # 生成警告,但仍然可以使用

输出:

1
10
10
英文:

Best practice is to pick the one that meets your needs. If you need someone using your class to use the getter and setter - for example to perform checks, or to take care of required side-effects - then that's what you should do.

If it's just an attribute that you're happy to have changed by other code (no side-effects) the first solution is fine.

Note that there's also @property decorators for a nicer way to do the second type - which would be best practice over these get_... and set_... methods:

class MyClassB():
    def __init__(self):
        self._my_attribute = 1

    @property
    def my_attribute(self):
        return self._my_attribute

    @my_attribute.setter
    def my_attribute(self, value):
        self._my_attribute = value

Note that adding the _ doesn't actually hide the attribute, it just generates warnings in editors that respect it:

b = MyClassB()
print(b.my_attribute)
b.my_attribute = 10
print(b.my_attribute)
print(b._my_attribute)  # generates a warning, but works all the same

Output:

1
10
10

答案2

得分: 1

在Python中,最佳实践是使用properties。属性看起来像属性,因此它们易于从客户端的角度使用和理解,但它们具有方法的所有灵活性和控制权。例如,您可以有一个矩形类的属性叫做area,它计算矩形的面积。

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    @property
    def area(self):
         return self.width * self.height

>>> my_rect = Rectangle(10, 20)
>>> my_rect.area
200
>>> my_rect.width = 5
>>> my_rect.area
100
英文:

In python, the best practice is to use properties. Properties "look" like attributes so they are easy to use and understand from the clients prospective but they have all the flexibility and control of methods. For example, you can have a property of a rectangle class called area that computes the area of the rectangle.

class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    @property
    def area(self):
         return self.width * self.height

>>> my_rect = Rectangle(10, 20)
>>> my_rect.area
200
>>> my_rect.width = 5
>>> my_rect.area
100

huangapple
  • 本文由 发表于 2023年7月4日 21:32:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定