Python 类实例在局部函数变量期间更改

问题描述

让我们例如定义一个类和一个函数

class class1(object):
    """description of class"""
    pass

def fun2(x,y):
    x.test=1;
    return x.value+y

然后定义一个类实例并将其作为函数中的局部变量运行

z=class1()
z.value=1
fun2(z,y=2)

但是,如果您尝试运行代码

z.test

将返回结果 1。

也就是说,尽管 x 的属性是在本地 fun2() 内部完成的,但它也全局扩展到类实例 x。这似乎违反了人们了解 python 函数的第一件事,除非被定义为非本地或全局,否则参数保持本地。

怎么会这样?为什么函数内部类的属性会扩展到函数外部。

解决方法

我还有更奇怪的例子:

def fun3(a):
    b=a
    b.append(3)
    
mya = [1]
fun3(mya)

print(mya)

[1,3]
> 

我将数组“复制”到一个局部变量,当我改变它时,全局变量也会改变。

问题在于参数不是通过值传递的(基本上是作为值的副本)。在python中,它们是通过引用传递的。在 C 术语中,该函数获取指向内存位置的指针。那样会快很多。

有些语言不允许您使用实例的私有属性,但在 Python 中,您有责任确保不会发生这种情况。 OOP 的另一条规则是您应该仅通过调用实例的方法来更改实例的内部状态。 但是您直接更改值。

Python 非常灵活,甚至可以让您做坏事。但它不会推动你。

我总是主张至少对任何高级语言的底层结构(内存模型、变量如何传递等)有模糊的理解。拥有一些 C/C++ 知识还有另一个论据。大多数高级语言都是用它们编写的,或者至少受到它们的启发。 C++ 程序员会清楚地看到发生了什么。