问题描述
|
我在这里使用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请求将使用一个比重新格式化每个服务的数据长一个数量级),可以吗?
这些函数中的ѭ5(总是有几个,不只是我的示例中的效用函数)总是可变的,但我想明确一点:函数的返回值表示确定性计算的结果我不喜欢使用out参数,但是在将可变结构传递给函数时,在Python中并没有解决此问题的方法。我考虑了几个选项:
复制将要突变的参数,以保留原始参数
我必须在每个要对其进行突变的函数中复制参数,这看起来很麻烦,就像我要重复很多一样。另外,我认为我实际上并不需要原始的,返回对我已经拥有的变异对象的引用似乎有些混乱。
只需将其用作输入/输出参数
我不喜欢这样,函数的作用还不是很明显,而且我认为它很丑。
创建一个装饰器,它将自动复制参数
似乎过分杀伤
那我在做什么呢?我感觉好像我在藏东西,将来的程序员可能会认为原始对象是根据我调用函数的方式保留的(抓住它的结果而不是依赖于它改变了原来的事实)。但是我也觉得任何其他选择都会很混乱。有没有更喜欢的方式?请注意,由于软件的工作方式,实际上并不是将mutator样式的方法添加到表示抽象数据的类中的选项(我将不得不添加一种方法来将该数据结构转换为相应的SOAP结构,我们也会发送每一项服务的数据-当前,翻译逻辑是针对每项服务单独包装的)
解决方法
如果您有很多这样的功能,我认为您最好的选择是编写一个包装该字典并就地对其进行修改的小类:
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
通常会期望修改自身的对象并且读取效果很好。