在python中模拟按值传递行为

Bor*_*lik 58 python pass-by-value

我想模仿python中的pass-by-value行为.换句话说,我想确保我写的函数不会修改用户提供的数据.

一种可能的方法是使用深层复制:

from copy import deepcopy
def f(data):
    data = deepcopy(data)
    #do stuff
Run Code Online (Sandbox Code Playgroud)

是否有更高效或更pythonic的方式来实现这一目标,尽可能少地假设传递的对象(如.clone()方法)

编辑

我知道技术上python中的所有内容都是按值传递的.我有兴趣模仿行为,即确保我不会混淆传递给函数的数据.我想最常用的方法是使用自己的克隆机制或深度复制来克隆有问题的对象.

Sku*_*del 32

你可以制作一个装饰器并将克隆行为放入其中.

>>> def passbyval(func):
def new(*args):
    cargs = [deepcopy(arg) for arg in args]
    return func(*cargs)
return new

>>> @passbyval
def myfunc(a):
    print a

>>> myfunc(20)
20
Run Code Online (Sandbox Code Playgroud)

这不是最强大的方法,并且不处理键值参数或类方法(缺少自我参数),但是你得到了图片.

请注意,以下陈述是相同的:

@somedecorator
def func1(): pass
# ... same as ...
def func2(): pass
func2 = somedecorator(func2)
Run Code Online (Sandbox Code Playgroud)

您甚至可以让装饰器采用某种功能来进行克隆,从而允许装饰者的用户决定克隆策略.在这种情况下,装饰器可能最好实现为具有__call__重写的类.

  • 我认为装饰器是解决这个问题的一种非常优雅的方法.我相信你可以提出一些可以应对关键词args的东西,而且没有太多麻烦. (2认同)

dF.*_*dF. 32

没有pythonic方式这样做.

Python提供了很少的工具来强制执行私有或只读数据.pythonic哲学是"我们都同意成年人":在这种情况下,这意味着"函数不应该更改数据"是规范的一部分,但在代码中没有强制执行.


如果您想复制数据,最接近的是您的解决方案.但是copy.deepcopy,除了是低效的,也有注意事项,例如:

因为深拷贝复制了它可能复制的所有内容,例如,即使在拷贝之间也应该共享的管理数据结构.

[...]

此模块不复制类型,如模块,方法,堆栈跟踪,堆栈帧,文件,套接字,窗口,数组或任何类似类型.

所以我只推荐它,如果你知道你正在处理内置的Python类型或你自己的对象(你可以通过定义__copy__/ __deepcopy__特殊方法来定制复制行为,不需要定义自己的clone()方法).


小智 10

例如,只有几个内置类型可用作引用list.

所以,对于我来说,在这个例子中,对于列表进行传值的pythonic方法是:

list1 = [0,1,2,3,4]
list2 = list1[:]
Run Code Online (Sandbox Code Playgroud)

list1[:] 创建list1的新实例,您可以将其分配给新变量.

也许你可以编写一个可以接收一个参数的函数,然后检查它的类型,并根据结果,执行一个内置操作,可以返回传递的参数的新实例.

正如我之前所说,只有少数内置类型,它们的行为就像引用一样,在这个例子中是列表.

无论如何......希望它有所帮助.

  • python中的所有内容都按值传递和分配.Python中的所有值都是引用.没有任何类型的工作方式与其他类型不同 (3认同)