2

我在这里使用 Python 工作(我认为这实际上是按名称传递的),但只要方法参数的行为相似,这个想法就与语言无关:

如果我有这样的功能:

def changefoo(source, destination):
    destination["foo"] = source
    return destination

并这样称呼它,

some_dict = {"foo": "bar"}
some_var = "a"

new_dict = changefoo(some_var, some_dict)

new_dict将是 的修改版本some_dict,但some_dict将被修改。

假设像我的示例中的 dict 这样的可变结构几乎总是同样小,并且性能不是问题(在应用程序中,我正在获取抽象对象并更改为不同服务的 SOAP 请求,其中 SOAP 请求将接受订单比重新格式化每个服务的数据要长得多),这样可以吗?

destination这些函数中(有几个,它不仅仅是像我的示例中那样的实用函数)将始终是可变的,但我想明确一点:函数的返回值表示对您传递的参数进行确定性计算的结果我不喜欢使用 out 参数,但是在将可变结构传递给函数时,在 Python 中并没有真正的解决方法。我考虑了几个选项:

  • 复制将要变异的参数,以保留原始参数

    我必须在我对其进行变异的每个函数中复制参数,这看起来很麻烦,就像我只是重复了很多。另外,我认为我实际上不需要原始文件,返回对我已经拥有的变异对象的引用似乎很麻烦。

  • 只需将其用作输入/输出参数

    我不喜欢这个,这个函数在做什么并不是很明显,而且我认为它很难看。

  • 创建一个会自动复制参数的装饰器

    好像有点矫枉过正

那我做的好吗?我觉得我在隐藏一些东西,未来的程序员可能会认为基于我调用函数的方式保留了原始对象(获取其结果而不是依赖于它改变原始对象的事实)。但我也觉得任何替代方案都会很混乱。有没有更优选的方式?请注意,由于软件的工作方式,向表示抽象数据的类添加 mutator 样式的方法并不是一个真正的选择(我必须添加一个方法来将该数据结构转换为我们的每个服务的相应 SOAP 结构也发送该数据-当前翻译逻辑位于每个服务的单独包中)

4

1 回答 1

1

如果你有很多这样的函数,我认为你最好的选择是编写一个包装 dict 并就地修改它的小类:

class DictMunger(object):
    def __init__(self, original_dict):
        self.original_dict = original_dict

    def changefoo(source)
        self.original_dict['foo'] = source

some_dict = {"foo": "bar"}
some_var = "a"

munger = DictMunger(some_dict)
munger.changefoo(some_var)
# ...
new_dict = munger.original_dict

修改自身的对象通常是预期的并且读起来很好。

于 2011-05-28T06:38:28.733 回答