为什么python无参函数可以调用作用域外的对象
class A:def __init__(self):
self.a = 100
a = A()
def add():
a.a += 20
add()
print(a.a)
## 输出结果:120
想问一下为什么add()可以调用作用域外的a.a
a.a并没有传参进去,也没有用关键字global 在Python中,函数可以访问作用域外的对象是因为Python解释器在查找变量时采用了一定的规则。这个规则被称为"LEGB"规则,即Local、Enclosing、Global和Built-in。
当函数内部引用一个变量时,Python解释器会按照以下顺序查找该变量:
1. Local(局部):首先在函数内部查找是否存在该变量。
2. Enclosing(封闭的父级函数):如果在函数内部没有找到该变量,就会继续查找外层函数是否定义了这个变量。
3. Global(全局):如果在封闭的父级函数中也没有找到该变量,就会在全局作用域中查找是否存在该变量。
4. Built-in(内建):如果都没有找到,最后会在Python的内建命名空间中查找。
在你提供的代码中,函数add()内部引用了变量a.a,而在该函数的封闭环境中并没有定义这个变量。接着,Python解释器根据LEGB规则去查找这个变量。由于在Global作用域中找到了a,所以可以进行访问和修改。
需要注意的是,如果要在函数中修改全局变量的值,必须使用global关键字来声明。但是在你提供的代码中,并没有修改全局变量a,而是修改了a.a。因此,不需要使用global关键字。
希望这个解释对你有帮助!如果还有其他问题,请随时提问。
球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:} 在Python中,函数可以访问并修改作用域外的对象,无论是全局作用域还是嵌套作用域。这是因为在Python中,函数在访问变量时会按照一定的顺序查找变量的定义。
在你的代码中,函数 add() 可以访问作用域外的 a.a ,因为在函数内部没有定义同名的局部变量 a.a 。当函数 add() 试图访问变量 a.a 时,它会按照以下顺序查找变量的定义:
1. 首先,它会查找函数内部的局部作用域,也就是 add() 函数内部是否有定义同名的局部变量 a.a 。
2. 如果在局部作用域中找不到对应的变量,它会继续在嵌套的作用域中查找。在这种情况下,嵌套作用域是全局作用域。
3. 如果在嵌套作用域中找到了对应的变量,函数就可以访问并修改它。
所以,在你的代码中,函数 add() 可以访问并修改作用域外的 a.a ,因为它在嵌套作用域中找到了对应的变量。这种行为不需要使用 global 关键字,因为没有需要在函数内部重新定义的同名局部变量。 你这个a不是全局变量嘛 yinda_peng 发表于 2023-11-4 22:18
你这个a不是全局变量嘛
class A:
def __init__(self):
self.a = 100
b = 10
a = A()
def add():
b += 10
a.a += 20
add()
print(a.a)
print(b)你看看这段代码全局变量b就会报错
b = 10
def add():
b += 10
add()
print(b)
兄弟们咋回事啊,变量就会报错,实例对象就不会报错,
class A:
def __init__(self):
self.a = 100
a = A()
def adda():
a.a +=10
adda()
print(a.a)
我去运行了一下,第一个的报错是:
UnboundLocalError: local variable 'b' referenced before assignment
意思是在赋值之前引用了局部变量“b”。我就记起来这个是要用global的,b本来是全局变量,在函数add()内部,当你尝试修改b的值时,Python会将其视为新的局部变量,并且你不能直接修改全局变量的值。
总的就是,全局变量和实例对象的作用范围这种,可以说是规则吧是不同的,对于全局变量,你要用global来修改其值,而对于实例对象的属性,你可以直接通过实例对象来访问和修改。这种东西有时候没有个为什么,因为像是个规则一样的,自己记住就好,就是这种区别,但是我讲一下自己的理解吧(不一定对):
变量的作用域是由其定义的位置决定的。全局变量是在函数外部定义的,可以在整个程序中访问。而局部变量是在函数内部定义的,只能在函数内部访问。在函数内部修改一个全局变量时,Python会将其当作一个新的局部变量处理,而不可以直接修改全局变量的值。我觉得这种设计像在大型程序中,都说全局变量的使用应该尽量避免嘛。通过将变量限定在函数内部或类的实例中,可以减少变量之间的相互影响,提高代码的模块化和可重用性。然后说类,类和对象嘛,对象就是可以有自己的属性,有自己的一种特定的属性方法一样的,设计这样的一种访问调用规则可以用起来更加方便灵活
个人的解答和看法,如有错误还请包涵
页:
[1]