我在这里使用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
(有几个,它不仅仅是我的例子中的实用函数)总是可变的,但我喜欢显式:函数的返回值表示结果对传入的参数进行确定性计算。我不喜欢使用参数,但在将可变结构传递给函数时,Python中并没有真正解决这个问题的方法。我仔细研究了几个选项:
复制将要变异的参数,以保留原始
我必须在我变异的每个函数中复制参数,这看起来很麻烦,而且我只是复制很多。另外我不认为我实际上需要原始版本,返回对我已经拥有的变异对象的引用似乎很麻烦。
只需将其用作输入/输出参数
即可我不喜欢这个,这个功能正在做什么并不是很明显,我认为这很难看。
创建一个装饰器,它将自动复制参数
似乎有点矫枉过正
那我正在做什么好吗?我觉得我隐藏了一些东西,未来的程序员可能会认为原始对象是基于我调用函数的方式保留的(抓住它的结果而不是依赖于它改变原始的事实)。但我也觉得任何替代方案都会很混乱。有更优选的方式吗?请注意,由于软件的工作方式,将mutator样式方法添加到表示抽象数据的类中并不是一个真正的选项(我必须添加一个方法将该数据结构转换为的相应SOAP结构每个服务我们也会发送这些数据 - 目前翻译逻辑位于每个服务的单独包中)
答案 0 :(得分: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
通常需要修改自身的对象并且读取效果很好。