有几次我不小心修改了函数的输入。由于 Python 没有恒定的引用,我想知道什么编码技术可以帮助我避免经常犯这种错误?
Example:
class Table:
def __init__(self, fields, raw_data):
# fields is a dictionary with field names as keys, and their types as value
# sometimes, we want to delete some of the elements
for field_name, data_type in fields.items():
if some_condition(field_name, raw_data):
del fields[field_name]
# ...
# in another module
# fields is already initialized here to some dictionary
table1 = Table(fields, raw_data1) # fields is corrupted by Table's __init__
table2 = Table(fields, raw_data2)
当然,修复方法是在更改参数之前复制该参数:
def __init__(self, fields, raw_data):
fields = copy.copy(fields)
# but copy.copy is safer and more generally applicable than .copy
# ...
但它很容易忘记。
我半信半疑地在每个函数的开头复制每个参数,除非该参数可能引用一个大型数据集,而该数据集的复制成本可能很高,或者除非该参数打算被修改。这几乎可以消除问题,但会导致每个函数的开头出现大量无用的代码。此外,它本质上会覆盖 Python 通过引用传递参数的方法,这可能是有原因的。
第一条一般规则: 不要修改容器:创建新容器。
因此,不要修改传入的字典,而是使用键的子集创建新字典。
self.fields = dict( key, value for key, value in fields.items()
if accept_key(key, data) )
此类方法通常比无论如何都检查并删除坏元素更有效。更一般地说,避免修改对象并创建新对象通常更容易。
第二条一般规则: 假冒容器后请勿对其进行修改。
您通常不能假设已向其传递数据的容器已制作了自己的副本。因此,不要尝试修改您提供给他们的容器。任何修改都应在移交数据之前完成。一旦您将容器交给其他人,您就不再是它的唯一主人。
第三条一般规则: 不要修改不是您创建的容器。
如果您收到某种容器,您不知道还有谁可能在使用该容器。所以不要修改它。使用未修改的版本或调用rule1,创建一个包含所需更改的新容器。
第四条一般规则:(从伊森·弗曼那里盗来的)
一些功能是应该修改列表。那是他们的工作。如果是这种情况在函数名称中明确这一点(例如列表方法追加和扩展)。
把它们放在一起:
仅当一段代码是唯一有权访问该容器的代码时,才应修改该容器。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)