繁体   English   中英

直接在 function 中更改 object 是 python 中的反模式?

[英]Change object directly in function is anti-pattern in python?

假设我们必须得到一些值并将其从 function 更改。

方式一

def change_b(obj):
    obj['b'] = 4


result = {'a': 1, 'b': 2}
change_b(obj=result)
print(result)

如您所知,function change_b change_b()直接在 function 中更改result['b']的值。

方式二

from copy import deepcopy


def change_b(obj):
    temp = deepcopy(obj)
    temp['b'] = 4
    return temp


result = {'a': 1, 'b': 2}
result = change_b(obj=result)
print(result)

但是方式 2将 object 复制到新的 object 并从新的 object 替换值。

所以,原来的 object 不会影响任何东西。 (而且,没有副作用)

也许Way-2更安全,因为它不会改变原来的object。

我想知道哪一种更通用和pythonic的方式?

谢谢。

概括

如果 API 明确表示它正在更新其输入,则Way-1很好且可取: add_route(route_map, new_route)

如果 API 主要是为了做其他事情,那么Way-2可以避免意外的副作用。

Python 中的示例

方式 1dict.update()list.sort()进行就地更新,因为这是它们的主要工作。

方式 2 :内置的sorted() function 从其输入中生成一个新的排序列表,注意不要更改。 大致来说,它是这样做的:

def sorted(iterable, *, key=None, reverse=False):
    result = list(iterable)                # copy the data
    result.sort(key=key, reverse=reverse)  # in-place sort
    return result

希望澄清何时复制以及何时就地变异:-)

“显式胜于隐式”
...
“面对模棱两可,拒绝猜测的诱惑。”

- PEP 20


修改 function 中的参数不一定是坏事。 不好的没有充分理由这样做。 如果您清楚您的 function 名称和文档将在 function 中修改参数,那很好。 如果 function 修改了参数而没有任何迹象表明它正在尝试这样做,那就不太好了。

在这种情况下,您的Way-1更简单、更明确。 很明显,变量将被更改,并且通过查看代码可以轻松确定更改的方式。

方式 2更糟糕,因为名称change_b意味着参数将被修改,而不是. 返回参数的修改版本而不修改原始版本是 python 中的标准设计模式,但最好明确说明。

例如,python 内置的set数据结构有对应的方法: set.difference(other)set.difference_update(other) 在这两种情况下,它们都做同样的事情:计算这个集合和给定集合之间的差异。 在前一种情况下,返回结果而不修改原始集。 在后一种情况下,原始集合被修改并且不返回任何内容。 弄清楚哪个做什么是非常简单的。

一般来说,您可能应该避免更新一个值返回相同的值,因为这更加模棱两可。 请注意大多数 python 方法如何做一个或另一个,但不是两者都做(以及同时做这两个的方法,如list.pop() ,这样做是明智的,返回的 object 不是经过修改的 ZA8CFDE6331BD59EB2AC96F8911C4B666)。

据我了解 Python,解决此问题的最 Pythonic 方法是非常清楚正在发生的事情。 只要你这样做,我认为这并不重要。

my_dict = {'a': 3, 'b': 4}
double_values_in_dict(my_dict)

# Some other code

这是一个人为的例子,但很清楚这里打算发生什么,即使没有包含方法定义。 不清楚的是,如果您将double_values_in_dict的返回值分配给一个新变量; 那时我不知道您可能对原始dict object 做了什么,我必须开始深入研究该方法以弄清楚它是如何工作的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM