86

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

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

4

8 回答 8

116

在 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

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

于 2010-04-05T18:16:52.493 回答
60

很酷的链接:Python 不是 Java :)

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

于 2010-04-05T17:31:13.270 回答
31

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

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

Guido:这通常意味着他们正在尝试继续他们的习惯,这些习惯适用于不同的语言。

[...] 人们会将所有东西都变成一个类,并将每个访问都变成一个访问器方法,
这在 Python 中确实不是明智的做法;您将拥有更
难以调试且运行速度更慢的冗长代码。您知道“您可以用任何语言编写 FORTRAN”这句话吗?您也可以用任何语言编写 Java。

于 2010-04-05T17:54:29.237 回答
15

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

于 2010-04-05T17:31:27.310 回答
7

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

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

于 2010-04-05T18:41:18.023 回答
5

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

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

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

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

于 2010-04-05T17:57:24.087 回答
0

我来这里是为了那个答案(不幸的是我不能)。但我在其他地方找到了工作。下面的代码可以替代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 方法。

于 2019-03-13T04:34:54.180 回答
-11

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

class Woman(Human):
    def getAge(self):
        if self.age > 30:
            return super().getAge() - 10
        else:
            return super().getAge()
于 2015-05-05T07:09:22.053 回答