Python:关于变量范围的后续操作。为什么我可以在def a中更改x.a的全局值?

Python:关于变量范围的后续操作。为什么我可以在def a中更改x.a的全局值?,python,variables,global-variables,scope,Python,Variables,Global Variables,Scope,作为后续行动 为什么我可以在def a中更改x.a的全局值?我猜这与它是一个类这一事实有关,因为它不会与正则变量一起工作,因为它会在defa的局部范围内被重新定义,但我不太了解发生了什么 案例1 class X: def __init__(self): self.a = 1 self.b = 2 self.c = 3 class Y: def A(self): print(x

作为后续行动

为什么我可以在
def a
中更改
x.a
的全局值?我猜这与它是一个类这一事实有关,因为它不会与正则变量一起工作,因为它会在
defa
的局部范围内被重新定义,但我不太了解发生了什么

案例1

class X:    
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

class Y:        
    def A(self):        
        print(x.a,x.b,x.c)
        x.a = 4           

x = X()
y = Y()
y.A()

print(x.a,x.b,x.c)

可以在函数中读取全局名称:

x = 5
def read_x():
    print(x)
x = [1, 2, 3]
def mutate_x():
    x[0] = 'One'
引用可变类型的全局变量也可以在函数中进行变异:

x = 5
def read_x():
    print(x)
x = [1, 2, 3]
def mutate_x():
    x[0] = 'One'
在函数范围内,您不能对全局函数执行赋值操作:

x = 5
def set_x():
    # this simply assigns a variable named x local to this function -- it doesn't modify the global x
    x = 3
# now, back outside the scope of set_x, x remains 5
print(x)
5
除非在函数范围内显式声明全局变量:

x = 5
def set_x():
    global x
    x = 3
# back outside the function's scope
print(x)
3
您在示例中所做的是“变异”——修改对象的属性。为用户定义类型的属性赋值是一个变异的例子,就像修改列表或字典的元素一样。这就是为什么这样做。

如果在
A
范围中设置
x=Y()
,它将在该范围中创建一个本地
x
。但是,在这种情况下,您不是在设置
x
,而是在设置
x.a
查找变量时也会考虑全局变量。假设您正在这样做
setattr(x,“a”,4)
,它会更有意义


另外,如果我没记错的话,您可以使用
global
关键字将全局变量“导入”到函数范围中。(请参见)

A没有定义x的init方法,因此方法A在尝试访问x的属性A时,尝试在局部范围内查找x对象,因为它找不到它,所以它会查找存在对象名x的外部范围,它会抓住该对象并覆盖属性a

因此,基本上您要做的是修改在调用y.a()之前创建的对象x的实际属性a

这是闭包的最基本的基础:访问一个定义在局部作用域之外的变量。< /P>