Python实践:通过“引用”传递的参数

时间:2011-08-09 13:02:21

标签: python arguments

考虑一个类的实例:

class Car(object):
    def __init__(self):
        self.engine = None

修改该实例的函数:

def add_engine(car):
    car.engine = 'V6'

Python没有隐含的技巧来指出将修改参数。我能想到的最好的解决方案是返回修改后的对象(即使它将作为参数传递给同一个对象):

def add_engine(car):
    car.engine = 'V6'
    return car

您如何解决此设计问题?

-

伙计们,非常感谢您的回答。你的建议有助于清除我头脑中的混乱:)

5 个答案:

答案 0 :(得分:7)

FWIW,我注意到在Python世界中,有副作用的函数/方法(例如你要问的那个)总是返回None。 (这是通过使用不带参数的return语句或完全忽略return来隐式完成的。)

例如,比较sorted内置函数,它返回一个新列表(当然已经排序),并返回list.sort方法,返回None,因为在这种情况下列表已按顺序排序。类似的情况适用于reversed内置函数和list.reverse方法。

因此,IMO,只是让你的函数(隐式)返回None就足以提醒用户这个函数有副作用的事实(因为,没有副作用,一个总是返回的函数{{ 1}}基本上是一种无操作的传统“Pythonic”方式。

答案 1 :(得分:4)

我倾向于制作返回self的方法。这允许像

这样的结构
car = Car().add_engine().add_wheels()

另一个选项,有时在Python标准库中使用,不返回任何内容。这应该可以防止混淆并在客户端使用破坏性更新时强制使用命令式样式。 list.sortsorted就是一个例子。

选择是样式之一,因此适用与周围代码一致的通常规则。

答案 2 :(得分:2)

我会完全不同地解决它:

class Car(object):
    def __init__(self):
        self.engine = None

    def set_engine(self):
        self.engine = 'V6'

惯例是add 附加数据; set改变现有状态。正如@larsmans指出的那样,汽车的回归使得它具有吸引力的结构,但它并没有解决你的问题。

答案 3 :(得分:2)

Python不像C ++,Java,C#等。你可以做任何你喜欢的事情。你不能私有化。你不能强制执行常量。

Python的这些方面有好处和缺点,但它就是这样。因为可以静态检查这么少,所以需要对代码进行非常强大的运行时测试,并且具有出色的覆盖率。如果没有完全覆盖的强大测试,Python中的开发可能会变得像放牧猫一样。

答案 4 :(得分:0)

您可以使用__setattr__方法覆盖属性分配:

class Car(object):
    def __init__(self):
        self.engine = None
    def car_modified(self, name):
        #do whatever you want
    def __setattr__(self, name, value)
        self.__dict__[name] = value
        self.car_modified(name)

每次设置属性时都会调用car_modified