在 Python 中使用访问器的正确方法? [复制]

Posted

技术标签:

【中文标题】在 Python 中使用访问器的正确方法? [复制]【英文标题】:Correct way to use accessors in Python? [duplicate] 【发布时间】:2013-03-20 08:56:16 【问题描述】:

这就是在 Python 中定义具有属性“Speed”的类“Car”的方式吗?我的背景是 Java,似乎没有人在 Python 中使用 get/set 方法。

class Car(object):
    def __init__(self):
        self._speed = 100

    @property
    def speed(self):
        return self._speed

    @speed.setter
    def speed(self, value):
        self._speed = value

【问题讨论】:

在 Python 中通常不使用 get/set 访问器,而是直接更改/获取对象值。你在变量名前使用了下划线——为什么要使用私有变量?这通常不是 ,,pythonic 的方式。请参阅此处了解更多信息:***.com/questions/551038/… 【参考方案1】:

在 Python 中,我们通常避免 getter 和 setter。只要有一个.speed 属性:

class Car(object):
    speed = 0

    def __init__(self):
        self.speed = 100

请参阅 Python is not Java 了解动机和要避免的更多陷阱:

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

当您在获取、设置或删除属性时确实需要执行代码时,请使用property。验证、缓存、副作用等都是属性的合理用例。在必要之前不要使用它们。

【讨论】:

是的,在这种情况下,我认为房产是正确的选择。 @lol:验证是使用@property 的有效用例。 @lol:任何与属性名称不同的东西。使用_speed 是一个很好的约定;前导 _ 说明它是私有属性,不会与属性名称冲突。 这实际上不是声明了一个类属性,而不是一个实例属性吗? @MartijnPieters 那么为什么要定义类属性呢?【参考方案2】:

我会选择属性,比如:

class Car(object):
    def __init__(self):
        self.speed = 100

您可以以完全相同的方式更改和获取它。 @property 符号可能更多地用于包装使用 Java/C get/set 方法、虚拟属性的类,或者如果您需要操作正在输入的值。

我经常在 GUI 类中使用它,我可以轻松地根据小部件的更改属性强制重绘屏幕,这是一种自定义事件系统。

【讨论】:

【参考方案3】:

由于技术上的属性在 Python 中永远不会是私有的,因此 get/set 方法不被视为“pythonic”。这是访问对象属性的标准方法:

class MyClass():
    def __init__(self):
        self.my_attr = 3

obj1 = MyClass()
print obj1.my_attr #will print 3
obj1.my_attr = 7
print obj1.my_attr #will print 7

当然,您仍然可以使用 getter 和 setter,并且可以通过在属性前加上 __ 来模拟私有成员:

class MyClass():
    def __init__(self):
        self.__my_attr = 3
    def set_my_attr(self,val):
        self.__my_attr = val
    def get_my_attr(self):
        return self.__my_attr

obj1 = MyClass()
print obj1.get_my_attr() #will print 3
obj1.set_my_attr(7)
print obj1.get_my_attr() #will print 7

__“破坏”变量名:在定义了__attr的某个类classname之外,__attr被重命名为_classname__attr;在上面的例子中,我们可以简单地使用obj1._MyClass__my_attr,而不是使用getter 和setter。所以__ 不鼓励外部使用属性,但它不像Java private 修饰符那样禁止它。

正如您在问题中提到的,Python 中还有可用的属性。属性的优点是您可以使用它们来实现返回或设置值的函数,这些值从类外部看起来像普通成员属性一样简单地访问。

【讨论】:

是的,我忘了更改为实际的方法语法。对不起。

以上是关于在 Python 中使用访问器的正确方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Python:迭代器的简单理解

二十三Python 中 property() 函数及 @property 装饰器的使用

如何在 Python 中正确使用私有函数? [复制]

在 Python 中,如何获取带参数传递给装饰器的函数名称?

如何在其他类/模块中正确导入/使用我在 Python 中构建的类和模块? [复制]

使用 GNU 链接器的正确方法