您是否使用get / set模式(在Python中)?


82

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

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


大家的好评。诚然,这个问题是这个stackoverflow.com/questions/1022970/的分支。但是,似乎我被一群从“ J”字眼看的人突袭了。再次感谢您恢复了我对理智的信念...
艾利·佩恩

1
上下文很重要,这里的Python和Java完全不同。(但是,我从标题中删除了Python,因为我们在SO上使用了标签。)

Answers:


59

酷链接:Python不是Java :)

在Java中,必须使用getter和setter,因为使用公共字段使您没有机会回头再改变主意,以后再使用getter和setter。因此,在Java中,您还可以避免繁琐的事情。在Python中,这很愚蠢,因为您可以从常规属性开始并随时改变主意,而不会影响该类的任何客户端。因此,请勿编写getter和setter。


3
加上setter / getter会增加性能成本,尤其是在Python中。
Nick Dandoulakis

4
确实给类设计者增加了负担,因为实例变量隐式地成为了类的公共API的一部分。在布置类时,应明确考虑要从外部访问哪些实例变量,而实际上只是那些属于类实现的一部分。内部实现的前缀以“ _”开头。这是Python警告标志,如果实现更改,则此变量可能也会更改甚至完全消失。否则,您会发现实现知识泄漏出您的课程,以后很难更改。
PaulMcG 2010年

8
@尼克D:我认为访问器不是在Python中进行速度优化的正确位置。
wRAR 2010年

1
@尼克D:我的意思是,这是一种解释性的语言,它鼓励可读性,而不是性能,因此在程序中有很多更好的地方可以进行优化。
wRAR'4

2
@Paul:它不是内部属性,除非使用一个或两个前划线来命名(通常首选第一种形式,因为后者会进行Python的异常名称修饰)。如果您不想编写文档并且此问题困扰您,则默认情况下,只需对所有实例属性使用_name即可。

113

在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

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


30

这是Guido van Rossum在《编程大师》中所说

“打架”是什么意思?

吉多:通常,这意味着他们正在尝试继续使用其他语言的良好习惯。

人们会把所有东西都变成一个类,并将每次访问都变成一个访问器方法,
在Python中这实际上不是明智的选择。您将拥有更多冗长的代码,这些代码
更难调试且运行速度慢得多。您知道“您可以用任何语言编写FORTRAN吗?”这一表达。您也可以用任何语言编写Java。


14

不,这是不可思议的。普遍接受的方法是使用常规数据属性,然后将需要更复杂的获取/设置逻辑的属性替换为属性。


13
+1:“我们都是成年人”。该代码是可见的。当可以看到所有代码时,“ private”和“ getter / setter”不会创建任何值。
S.Lott

7

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

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


5

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

我绝对同意所有以前的张贴者,尤其是@Maximiliano链接到Phillip的著名文章,以及@Max的建议,即比设置(和获取)类和实例属性的标准方法更复杂的事情是使用Properties(或Descriptor进行更广泛的概括)自定义属性的获取和设置!(这包括能够添加自己的私有,受保护的,朋友的自定义版本,或者如果您需要公开之外的其他内容,则可以添加您想要的任何策略。)

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

这是另一篇可能对您也有用的相关文章: Python:多个属性,一个setter / getter


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中构建获取/设置方法。


-10

我们的老师在课堂上展示了一个示例,解释了何时应使用访问器函数。

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

我没有给你低票,但我想我会提一下。讨论的重点是“为什么我们需要get()/ set()直接在Python中访问属性”。在Java中,有一些语言...功能...使它很理想。在Python中,没有那么多。
艾利·佩恩

7
除了未真正回答问题外,此回答中使用的示例令人反感。声称您的老师使用了它,并不能证明它的性别歧视。
赞2015年

我怀疑这表明性别歧视,仅仅是你的天真。在我祖母的这一代,许多妇女开玩笑说他们的年龄比实际年龄小了几岁。除此之外,它与答案无关。
约翰·斯诺果斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.