Python中关于变量作用域的问题请教

class a:
def init(self,val):
self.val=val

def add(self,other):

if isinstance(other,a):
print(“other 变量变化前 other=”,other) #语句 1
other=other.val
print(“other 变量变化后 other=”,other) #语句 2

return a(self.val+other)


x=a(8)
y=a(9)

print(“x+y 之前 y=”,y) #语句 3
print(“x+y=”,x+y)
print(“x+y 之后 y=”,y) #语句 4

上面代码的输出如下:
x+y 之前 y= <main.a object at 0x01F16270>
other 变量变化前 other= <main.a object at 0x01F16270>
other 变量变化后 other= 9
x+y= <main.a object at 0x01F16290>
x+y 之后 y= <main.a object at 0x01F16270>

我的问题是:
1、“ other=other.val ”这个语句中,other 在等号左边出现,是否可以认为 other 因此成为__add__的局部变量?
2、实例 y 对应的是__add__方法的 other 参数,从输出来看 other 变量在执行 x+y 前后已经发生了变化,那为何实例 y 在执行 x+y 后并没有变成 9,其地址始终不变?谢谢
Python中关于变量作用域的问题请教


4 回复

缩进乱掉了


在Python里,变量作用域的核心就四层:局部(Local)、闭包(Enclosing)、全局(Global)、内置(Built-in),也就是常说的 LEGB规则

简单说就是:当你用一个变量名时,Python会按 L -> E -> G -> B 这个顺序去找它。

看个典型例子就明白了:

x = "global"  # 这是全局变量

def outer():
    x = "enclosing"  # 这是闭包作用域变量
    
    def inner():
        x = "local"  # 这是局部变量
        print(f"inner sees: {x}")  # 输出 local
        
    inner()
    print(f"outer sees: {x}")  # 输出 enclosing

outer()
print(f"global sees: {x}")  # 输出 global

关键点:

  1. 局部变量优先:函数内部定义的变量,只在函数内有效
  2. global关键字:想在函数里修改全局变量时用
  3. nonlocal关键字:在嵌套函数里修改外层(非全局)变量时用

常见坑:

x = 10

def modify():
    # 这里会报错!因为Python看到 x = ... 就认为x是局部变量
    # 但 print(x) 时局部变量x还没定义
    print(x)
    x = 20

# 正确写法:
def modify_correct():
    global x  # 声明要修改全局变量
    print(x)  # 现在可以了
    x = 20

一句话建议: 写函数时变量作用域要清晰,避免内外同名混淆。

传进去的都是可重绑定的引用 绑定到了新对象

  1. other 是__add__的参数里定义的,所以它的作用域只在__add__()里有效
    2. other 和 y 本身是不同的两个引用,只是他们引用的是同一个东西罢了。你看看 id(other)和 id(y),应该是不同的。所以你更改了 other,让它去引用其他的东西,并不会影响到 y。
回到顶部