【问题标题】:Do you use the get/set pattern (in Python)?您是否使用 get/set 模式(在 Python 中)?
【发布时间】:2011-02-04 12:13:12
【问题描述】:

使用 get/set 似乎是 Java 中的一种常见做法(出于各种原因),但我几乎看不到使用它的 Python 代码。

为什么在 Python 中使用或避免使用 get/set 方法?

【问题讨论】:

标签: python getter-setter


【解决方案1】:

我来这里是为了那个答案(不幸的是我不能)。但我在其他地方找到了解决方法。以下代码可以替代 get
class get_var_lis: def __init__(self): pass def __call__(self): return [2,3,4] def __iter__(self): return iter([2,3,4]) some_other_var = get_var_lis
这只是一个解决方法。通过使用上述概念,您也可以轻松地在 py 中构建 get/set 方法。

【讨论】:

    【解决方案2】:

    在python中,你可以直接访问该属性,因为它是公共的:

    class MyClass:
    
        def __init__(self):
            self.my_attribute = 0  
    
    my_object = MyClass()
    my_object.my_attribute = 1 # etc.
    

    如果你想对属性的访问或突变做一些事情,你可以使用properties

    class MyClass:
    
        def __init__(self):
            self._my_attribute = 0
    
        @property
        def my_attribute(self):
            # Do something if you want
            return self._my_attribute
    
        @my_attribute.setter
        def my_attribute(self, value):
            # Do something if you want
            self._my_attribute = value
    

    至关重要的是,客户端代码保持不变。

    【讨论】:

      【解决方案3】:

      我们的老师在课堂上展示了一个例子来解释我们什么时候应该使用访问器函数。

      class Woman(Human):
          def getAge(self):
              if self.age > 30:
                  return super().getAge() - 10
              else:
                  return super().getAge()
      

      【讨论】:

      • 我没有给你反对意见,但我想我会插话。讨论的重点是“为什么我们需要 get() / set() 来直接在 Python 中访问属性” .在 Java 中,有一些语言……特性……使这变得可取。在 Python 中,没有那么多。
      • 除了没有真正回答问题外,此答案中使用的示例令人反感。您的老师使用它的说法并不能证明其性别歧视是正当的。
      • 我怀疑这表明性别歧视,只是你的天真。在我祖母那一代,许多女性开玩笑说她们的年龄比实际年龄小几岁。此外,无论如何它与答案无关。
      【解决方案4】:

      您的问题的简短回答是否定的,您应该在需要时使用属性。 Ryan Tamyoko 在他的文章 Getters/Setters/Fuxors

      中提供了长答案

      摆脱这一切的基本价值是,您要努力确保每一行代码对程序员都有一定的价值或意义。编程语言是为人类而不是机器设计的。如果您的代码看起来没有任何用处、难以阅读或看起来乏味,那么很有可能 Python 具有一些可以让您删除它的语言功能。

      【讨论】:

        【解决方案5】:

        这是 Guido van Rossum 在Masterminds of Programming 中所说的

        “与语言作斗争”是什么意思?

        Guido:这通常意味着他们是 试图继续他们的习惯 使用不同的语言效果很好。

        [...] 人们会把一切变成 一个类,并将每个访问变成一个 存取方法,
        在 Python 中这确实不是明智的做法; 您将获得更详细的代码,即
        更难调试并且运行速度更慢。 你知道表达“你可以写 任何语言的 FORTRAN?” 你也可以用任何语言编写 Java。

        【讨论】:

          【解决方案6】:

          你的观察是正确的。这不是 Python 编程的正常风格。属性都是公共的,因此您只需访问(获取、设置、删除)它们,就像使用具有它们的任何对象(不仅仅是类或实例)的属性一样。很容易判断 Java 程序员何时学习 Python,因为他们的 Python 代码看起来像使用 Python 语法的 Java!

          我绝对同意所有以前的海报,尤其是@Maximiliano 对 Phillip 著名文章的链接@Max 的建议,即任何比设置(和获取)类和实例属性的标准方法更复杂的方法是使用属性(或描述符来概括更多)来自定义属性的获取和设置! (这包括能够添加您自己的私有、受保护、朋友或任何您想要的策略的自定义版本,如果您想要公共以外的东西。)

          作为一个有趣的演示,在 Core Python Programming(第 13 章,第 13.16 节)中,我提出了一个使用描述符将属性存储到磁盘而不是内存的示例!是的,它是一种奇怪的持久存储形式,但它确实向您展示了一个可能的示例!

          这是另一个您可能会觉得有用的相关帖子: Python: multiple properties, one setter/getter

          【讨论】:

            【解决方案7】:

            不,它是非pythonic。普遍接受的方法是使用普通的数据属性,并将需要更复杂的 get/set 逻辑的属性替换为属性。

            【讨论】:

            • +1:“我们都是成年人”。代码可见。当所有代码都可以看到时,“private”和“getter/setter”不会创造任何价值。
            【解决方案8】:

            酷链接:Python is not Java :)

            在 Java 中,您必须使用 getter 和 setter,因为使用公共字段使您没有机会回头再改变主意以使用 getter 和 setter。因此,在 Java 中,您不妨先把繁琐的事情排除在外。在 Python 中,这很愚蠢,因为您可以从普通属性开始并随时改变主意,而不会影响类的任何客户端。所以,不要写 getter 和 setter。

            【讨论】:

            • 加上 setter/getter 会增加性能成本,尤其是在 Python 中。
            • 确实给类设计者增加了负担,因为实例变量隐式地成为类的公共 API 的一部分。在布局类时,明确考虑您希望从外部访问哪些实例变量与那些实际上只是类实现的一部分的实例变量。使用前导“_”作为内部实现的前缀。这是 Python 的警告信号,如果实现发生变化,这个变量可能也会发生变化,甚至完全消失。否则你会发现实现知识从你的课程中泄露出来,以后很难改变。
            • @Nick D:我认为访问器不是在 Python 中进行速度优化的正确位置。
            • @Nick D:我的意思是,这是一种解释性语言,它鼓励可读性,而不是性能,所以程序中会有很多更好的地方进行优化。
            • @Paul:它不是一个内部属性,除非它用一个或两个前导下划线命名(通常首选第一种形式,因为后者是 Python 不寻常的名称修饰)。如果您不想编写文档并且此问题困扰您,只需默认为所有实例属性使用 _name。
            猜你喜欢
            • 1970-01-01
            • 2013-10-21
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-10-19
            • 2010-09-09
            • 2010-12-11
            相关资源
            最近更新 更多