在Python中正确使用访问器的方法是什么?

2024-03-29 01:41:44 发布

您现在位置:Python中文网/ 问答频道 /正文

这就是在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

Tags: 方法selfget属性定义valuedef方式
3条回答

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

class Car(object):
    speed = 0

    def __init__(self):
        self.speed = 100

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

In Java, you have to use getters and setters because using public fields gives you no opportunity to go back and change your mind later to using getters and setters. So in Java, you might as well get the chore out of the way up front. In Python, this is silly, because you can start with a normal attribute and change your mind at any time, without affecting any clients of the class. So, don't write getters and setters.

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

我会选择属性,比如:

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

在那里你可以改变和得到完全一样的方式。@property符号可能更多地用于包装使用Java/C get/set方法、虚拟属性的类,或者如果需要操作输入的值。

我经常在GUI类中使用它,在那里,我可以根据widget的属性(类似于自定义事件系统)的变化轻松地强制重绘屏幕。

由于技术上属性在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。因此__不鼓励外部使用属性,但它并不像Java private修饰符那样禁止属性。

正如您在问题中提到的,Python中还提供了一些属性。属性的优点是,您可以使用它们来实现返回或设置值的函数,这些值在类之外似乎只是作为普通成员属性访问的。

相关问题 更多 >