【问题标题】:Confused about setters and getters [duplicate]对setter和getter感到困惑[重复]
【发布时间】:2018-08-15 00:01:10
【问题描述】:

我是一个新的 Python 程序员,我最近开始学习 Python 中的 @property 和 @setter 装饰器。但是我对它们在最简单的脚本中的使用感到困惑,例如:

class Aaron:
    def __init__(self,name):
       self.name = name
    @property
    def name(self):
       return self._name
    @name.setter
    def name(self,new):
        self._name = new

setter 和 getter 有什么用?,感谢任何帮助 谢谢

【问题讨论】:

  • property 装饰器和描述符通常是 Python 进行数据隐藏/封装的方式。不必编写一堆 biolerplate getter 和 setter,您可以从简单的属性访问开始,然后使用带有 property 的托管属性进行折射,而不会破坏您以前的代码。所以,在这种情况下,你不会使用它们
  • 您好,很抱歉打扰您,但您能否以更简单的方式解释 setter 和 getter,我无法理解您所写的内容,谢谢
  • 假设您的 name 属性,如果名称中包含数字,您想引发异常。 property 将允许您在将其分配给内部变量之前进行字符串/类型检查。
  • @AaronB 你将不得不提供更多关于你不明白的背景。听起来你最好阅读一篇介绍性的 OOP 教程,最好是一个面向 Pytho 的教程,这样你才能真正了解property,Python 中的 OOP 教程通常会使用类似 java 的 get_attr nd set_attr 方法不是pythonic
  • @AaronB 基本上你想让你的类的用户有可能改变一个属性的值,但是当你这样做时,你 1)想要在做之前验证这个更改,或者 2)触发更改此属性所需的事件。因此,您需要使用 getter/setter 以便对其进行管理。

标签: python properties setter getter


【解决方案1】:

Getter 和 Setter 只是帮助encapsulation 的方法。它们不是特定于 Python,而是一般的面向对象编程;

它们也被称为mutator/accessor 方法。

他们有什么意义?

它们隐藏了实现细节

您的班级的用户不需要知道您在内部使用的属性名称来跟踪您的Username。您只需告诉他们致电.getName() 以获取名称即可。

它们允许您添加验证检查

如果属性暴露给您任意更改,而不使用set 方法,您可能会做出错误的更改,例如将User 实例的名称设置为“12”。

您可以在实际改变属性之前执行其他工作

有时您可能希望保留发生在 你的实例。使用 setter 可以在实际更改属性值之前触发其他函数,例如调用 logNameChanges 方法。

这些是我实际遇到过的最重要的原因。有一个更详尽的列表here

【讨论】:

  • 嗯...你不告诉他们打电话给.getName(),那是Java的废话。 @property 的全部意义在于它可以制作像属性一样使用的东西,但可以完成方法的工作。特别是,您通常使用封装开始(如果不需要编程行为,普通的 name 属性被认为是完全 Pythonic 的),但如果您后来决定需要它来做一些事情验证或其他工作,您可以追溯将实际属性更改为 _name,然后将 name 定义为 @property,用户界面保持不变。
  • @ShadowRanger 太好了,请随时编辑答案的那部分。
  • 您还遗漏了一个常见用途,即定义 @property 而不使用 setter/deleter,以制作“只读”属性。由于它是 Python,因此它们并不是真正的只读(除非您使用 namedtuple 设置),因为底层的真实属性是可变的,但是如果您在底层属性前加上下划线,则记录了预期的“内部使用”只有”属性的方面;只读无前缀属性是唯一的公共接口。
【解决方案2】:

当您想要在设置或获取值时执行一些操作时,Setter 和 getter 非常有用,例如验证值是否有效,或记录访问,或修改另一个值。

例如,如果您有一个 Screen 类并希望保持 16:9 的纵横比,您可以这样写:

class Screen:
    def __init__(self):
       self._height = 1080
       self._width = 1920

    @property
    def height(self):
       return self._height
    @name.setter
    def height(self,new):
        self._height = new
        self._width = 16*self._height/9

    @property
    def width(self):
       return self._width
    @name.setter
    def width(self,new):
        self._width = new
        self._height = 9*self._width/16

【讨论】:

    猜你喜欢
    • 2014-03-18
    • 1970-01-01
    • 2015-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-04
    • 2023-03-10
    • 2020-08-21
    相关资源
    最近更新 更多