全局作用域的范围仅限于单个文件。在python中格式没有一个基于单个的、无所不包的情景文件的全局作用域。
Def/class/lambda三种方式
L:本地作用域;
E:上层结构中的本地作用域;
G:全局作用域;
B:内置作用域;
法则描述:
变量名引用分为四个作用域进行查找:LEGB,第一个能够完成查找的就算成功;
默认状态下,变量名赋值会创建或者改变本地变量;
全局声明将赋值变量名映射到模块文件内部的作用域;
需要讲的就这么多^_^
接下来,希望大家能自己慢慢去体会“引用”和“赋值”之间的区别,那将是对大脑的一种摧残。
以下内容中有很多问题跟python的内存管理机制和python语言自身的规则相关,目前还没有看到那么细的地步,所以会有不少解释不够清晰的,个人只能尽量保证正确吧,请各位抱着找茬的心态继续一起继续前行。
只能举例说明啦……
变量名赋值:
a、a = 1
a = 2
全局域申明一个变量a=1后,函数内部再去赋值的时,会重新创建一个新的本地局部变量a=2。
b、b = {}
c、c = []
d、t = (1, 2, 3)
e、……
变量名引用:
a、a = 1
b = a #b为赋值,a为引用,产生的结果是b与a一样都指向对数字1的引用,此时b和a的id应该是一样的
b、b = {}
b[‘name’] = ‘chenweiguo’
b[‘email’] = ‘chenweiguo@baidu.com’
#此时b所指引的内存空间并没有发生变化,只是新增了两个元素数据;
c、c = [1, 2, 3, 4]
c[2] = 6
对于列表c来说,这只是一次引用,改变的是内部的链表中的一个元素
d、……
应用和赋值应该都只是针对与变量关系最接近的这一级元素来说的。
全局变量是位于模块文件内部的顶层的变量名;
全局变量如果是在函数内被赋值的话,必须经过申明;
全局变量名在函数的内部不经过声明也可以被引用。
函数参数传递时,传递的都是引用;
不可变参数的应用传递后,如果数据发生改变,则会创建新的对象,降低原参数的引用,对原有数据不会产生影响;
可变参数在函数中引用时,可以改变调用函数中的数据;但如果是赋值,则会创建新的对象,对原有数据同样不影响。
见《python学习手册》第347页
可变对象参数:
dict(通过哈希+指针索引实现)、list(通过链表实现)
不可变对象参数:
int(long长度的内存空间)、string(连续内存空间)、tuple(在python源码分析中未找到该对象的介绍)与可变对象/不可变对象对应的还有一个概念:变长对象、定长对象
通过不可变对象来进行传递;
在函数内部主动做一次赋值操作,如:a = a[:];
通过return返回,python的返回值没有个数限制。
>>> id.__doc__ "id(object) -> integer\n\nReturn the identity of an object. This is guaranteed to be unique among\nsimultaneously existing objects. (Hint: it's the object's memory address.)"
通过宏定义实现,默认值为[-5, 257),小整数对象是为了减少python程序运行中对这些整数的频繁使用(申请和析构)带来的效率低下问题。相似的还有常用字符缓冲池。
另外,python对于大整数及其他需要使用内存的对象一样,并不是不停的通过malloc和free实现的,还是单独封装了一层内存的管理机制,尽量减少实际物理内存的malloc和free次数,提高效率。
文章来源:百度文库