在Python中模拟按值传递行为

9 浏览
0 Comments

在Python中模拟按值传递行为

我想在Python中模拟按值传递的行为。换句话说,我希望确保我编写的函数不修改用户提供的数据。

一种可能的方法是使用深拷贝:

from copy import deepcopy
def f(data):
    data = deepcopy(data)
    #做一些事情

是否有更高效或更符合Python风格的方法来实现这个目标,尽量少做关于传递对象的假设(比如.clone()方法)。

编辑

我知道从技术上讲Python中的一切都是按值传递的。我感兴趣的是模拟这种行为,即确保我不会对传递给函数的数据进行更改。我想最通用的方法是使用对象自身的克隆机制或深拷贝来克隆对象。

0
0 Comments

在Python中,函数参数在传递时通常是按引用传递的,这意味着传递给函数的参数实际上是指向原始对象的指针。这种行为有时可能会导致问题,尤其是在希望函数内部修改参数值而不影响原始对象时。为了解决这个问题,可以使用装饰器来模拟按值传递的行为。

下面是一个示例装饰器的代码:

def passbyval(func):
    def new(*args):
        cargs = [deepcopy(arg) for arg in args]
        return func(*cargs)
    return new
def myfunc(a):
    print a
myfunc(20)

这个装饰器将传递给函数的参数进行深拷贝,然后将拷贝后的参数传递给原始函数。这样做可以确保函数内部对参数的修改不会影响原始对象。

需要注意的是,装饰器目前只处理了普通参数,对于关键字参数和类方法(缺少self参数)还没有进行处理。但是可以通过进一步修改装饰器来解决这些问题。

另外,装饰器还可以接受一个函数作为参数,用于指定拷贝策略。这样一来,用户可以根据自己的需求决定如何进行拷贝。在这种情况下,最好将装饰器实现为一个类,并重写`__call__`方法。

装饰器是一种非常优雅的解决这个问题的方法。如果需要处理关键字参数,只需要给新的方法添加`**kwargs`参数并进行拷贝即可。

以上就是模拟Python中按值传递行为的问题的原因以及解决方法的整理。

0
0 Comments

在Python中,只有一些内置类型(如list)可以作为引用来使用。

因此,对于我来说,在这个例子中,对于列表来说,实现按值传递的Pythonic方式是:

list1 = [0,1,2,3,4]
list2 = list1[:]

list1[:]创建了一个列表list1的新实例,并且可以将其赋值给一个新变量。

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

正如我之前所说,只有很少的内置类型(如列表)的行为类似于引用。

无论如何...希望对你有所帮助。

Python中的一切都是通过值传递和赋值的。Python中的所有值都是引用。没有任何类型的工作方式与其他类型不同。

你的方法天真地实现了我想要的效果。谢谢。

0
0 Comments

在Python中没有一种Pythonic的方法来实现这一点。Python提供了很少的机制来强制执行诸如私有或只读数据之类的事物。Pythonic的哲学是“我们都是成年人”:在这种情况下,这意味着“函数不应该改变数据”是规范的一部分,但在代码中没有强制执行。

如果你想复制数据,你可以使用copy.deepcopy方法,但是它效率低下,并且还有一些注意事项,比如:

因为深拷贝会复制所有内容,它可能会复制太多内容,例如应该在副本之间共享的管理数据结构。

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

因此,我只建议在你知道你正在处理内置Python类型或自己的对象(可以通过定义__copy__ / __deepcopy__特殊方法来自定义复制行为,不需要定义自己的clone()方法)时使用它。

如果你必须使用deepcopy,那么实现自己的__deepcopy__通常会大大加快调用deepcopy的速度。

0