19

这是您如何在 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
4

3 回答 3

28

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

class Car(object):
    speed = 0

    def __init__(self):
        self.speed = 100

请参阅Python 不是 Java以了解动机和要避免的更多陷阱:

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

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

于 2013-03-29T16:13:27.347 回答
1

由于从技术上讲属性在 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

The __ "mangles" the variable name: from outside some class classname in which __attr is defined, __attr is renamed as _classname__attr; in the above example, instead of using the getters and setters, we could simply use obj1._MyClass__my_attr. So __ discourages external use of attributes, but it doesn't prohibit it in the same way that the Java private modifier does.

There are also, as you mention in your question, properties available in Python. The advantage of properties is that you can use them to implement functions that return or set values that, from outside the class, appear to be simply accessed as normal member attributes.

于 2013-03-29T16:22:08.477 回答
0

我会去寻找属性,比如:

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

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

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

于 2013-03-29T16:16:18.233 回答