Python中如何避免函数的副作用
我现在有许多函数,都是这样定义的:
def func1(context):
context_ = copy(context)
# do something
context_.xxx = xxxx
return context_
因为我不想因为副作用修改传入的参数,所以函数的首行,都 copy 了一下。 觉得这样有些重复,有没有什么方法,比如装饰器,或者 context manager,省去每次显式 copy 的做法?
ps: 我是有许多这样的函数,想创建一个 pipeline,为了简单就入参和出参一样了
Python中如何避免函数的副作用
不清楚 copy 是否有用,但是 copy.deepcopy 一定不会错。
装饰器搞得定。
在Python里,要避免函数副作用,核心就是让函数成为“纯函数”——只依赖输入参数,不修改外部状态,并且每次相同输入都返回相同输出。
最直接的方法是:函数内部不修改传入的可变对象(如列表、字典),也不依赖或修改全局变量、类属性等外部状态。
举个例子,下面这个函数有副作用,它直接修改了传入的列表:
def add_to_list(item, target_list):
target_list.append(item)
return target_list
my_list = [1, 2, 3]
new_list = add_to_list(4, my_list)
print(my_list) # 输出 [1, 2, 3, 4] —— 原列表被改了!
要避免这个副作用,函数应该创建并返回一个新列表:
def add_to_list_pure(item, target_list):
# 创建原列表的副本,避免修改输入
new_list = target_list.copy()
new_list.append(item)
return new_list
my_list = [1, 2, 3]
new_list = add_to_list_pure(4, my_list)
print(my_list) # 输出 [1, 2, 3] —— 原列表保持不变
print(new_list) # 输出 [1, 2, 3, 4]
对于字典等可变对象也一样,使用.copy()方法或dict()构造函数创建副本。对于嵌套结构,可能需要copy模块的deepcopy。
另外,避免使用global关键字在函数内修改全局变量。如果函数需要“记忆”状态,考虑使用闭包或类来显式地管理。
总结:写纯函数,操作副本而非原件。
在调用前复制一下入参不行么?所有的函数调用都不想改入参?需要改入参的情况才是常态吧?
装饰器的典型应用场景…
面向切面了解一下.
避免函数的副作用的正确方法就是不写函数,不写函数就不用传参,不传参就不用担心副作用,不写函数就不用调用,像写作文一样去写
那还怎么维护
维护不是别人的事吗,写完你就该撤了
为什么不写类来表达上下文?
一个对象内部的数据就可以作为上下文
哦,楼主的重点是每次要复制一份新的上下文来用哈
写一个专门的复制函数复制你的 context
用装饰器加复制函数实现预复制功能
!!! 这种思想能写好程序?对自己的代码负责,ok ?
每个函数开头都 copy 一下?浪费了 memory 又拖慢了 performance
封装好 context, 只给特定的代码修改权限呗
因噎废食,熟练掌握语言,知道哪些操作会修改对象哪些不对,在纯函数里不在参数上调用那些会修改对象的函数 /方法就可以了
不要故意带歪路。


