python全局变量赋初值_python 全局变量

python全局变量赋初值_python 全局变量理解的都没问题。但我想聊聊出现这种情况的原因。在讲原因之前,需要先知道python中变量的搜索顺序,这个顺序是LGB(不考虑闭包情况)即local本地,global全局,builtin内建。比如:a=1deftest():a=3print(a)test()函数内声明了局部变量a,在打印中使用,在本地环境中命中,因此使用的是3。也许你会问这个知识点我早就知道了,这和本问题有什么关…

大家好,欢迎来到IT知识分享网。python全局变量赋初值_python 全局变量

理解的都没问题。但我想聊聊出现这种情况的原因。在讲原因之前,需要先知道python中变量的搜索顺序,这个顺序是 LGB (不考虑闭包情况)即local本地,global全局,builtin内建。比如:

a = 1

def test():

a = 3

print(a)

test()

函数内声明了局部变量 a ,在打印中使用,在本地环境中命中,因此使用的是 3。

也许你会问这个知识点我早就知道了,这和本问题有什么关系呢?

有的,难道你不觉得奇怪吗?报错是变量未初始化,而不是变量未定义。

题目中函数内 c= c+1 就已经表明了声明的变量 c 是属于局部变量的。 按理说,先执行赋值语句右侧,而此时 c 并没有声明,应该在全局环境命中才对啊。所以想象中的结果应该是局部变量 c = 2 而全局变量的 c 保持原值。

但是,这只都是想当然。讲了这么多其实我是想引出,python虽然是动态语句,但它还是会对代码做扫描工作的,会有收集有用的静态信息。函数的应该信息会放在 code 对象中,里面的信息就包含了局部变量名称的集合,可以通过 co_varnames 得到,如下:

c = 1

def test():

c= c+1

a = 3 # 另一个局部变量

print(c)

print(test.__code__.co_varnames) # (‘c’, ‘a’)

因此,函数test在执行前,变量 c 就已经被声明在局部变量环境中了,而不是我们自认为的当赋值语句运行后才会在局部变量里。于是,这就导致了报错信息是变量未初始化而不是变量未定义。

====== 分割线 =========

题主评论要求:

关于变量的初始化,定义,创建这三者关系,能帮忙疏导一下理解吗?

这三个意思基本差不多,没必要分得太开。把变量环境理解成一个字典 name_env = dict() 其实就很好理解了(事实上python底层也确实是这样处理的)。对于在这个环境内要创建一个名为 a 的变量,就可以是 name_env[‘a’] = value 的形式了。

这个过程也就是赋值语句形如 a = value 时会调用赋值的指令 STORE_NAME 。我们看一下这个赋值过程你就理解了。

这部分代码在 ceval.c 中,详见 ceval.c

TARGET(STORE_NAME) {

PyObject *name = GETITEM(names, oparg);

PyObject *v = POP();

PyObject *ns = f->f_locals;

int err;

if (ns == NULL) {

PyErr_Format(PyExc_SystemError,

“no locals found when storing %R”, name);

Py_DECREF(v);

goto error;

}

if (PyDict_CheckExact(ns))

err = PyDict_SetItem(ns, name, v);

else

err = PyObject_SetItem(ns, name, v);

Py_DECREF(v);

if (err != 0)

goto error;

DISPATCH();

}

代码不多,可以逐个分析下,第一行获得的 name 就是赋值语句 a = value 的 a,a以python类型 str 形式存在。第二行 v 从栈中获取,也就是 value 的值。第三行 ns 是从帧对象中获得局部变量环境(大多数情况下是个字典类型,如果帧环境不在函数或类中,取得的是全局变量环境)。PyDict_SetItem(ns, name, v); 和 PyObject_SetItem(ns, name, v); 就可以理解为 ns[name] = v 和 setattr(ns, name, v) 了,创建过程就是这样了。

变量究竟是创建还是初始化还是覆盖已有的变量值,其实底层并不关心。

回到本地中,本地变量的符号表会保存在静态信息里面,我猜测搜索变量时有优先去静态信息中得到信息,来更快的知道变量应该是在局部还是全局中查找吧。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/22978.html

(0)
上一篇 2023-12-18 11:00
下一篇 2023-12-19 17:00

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信