说明:
命名空间(Namespace)是从名称到对象的映射,大部分的命名空间都是通过 Python 字典来实现的。命名空间提供了在项目中避免名字冲突的一种方法。各个命名空间是独立的,没有任何关系的,所以一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。一般有三种命名空间:
内置名称(built-in names), Python 语言内置的名称,比如函数名 abs、char 和异常名称 BaseException、Exception 等等。全局名称(global names),模块中定义的名称,记录了模块的变量,包括函数、类、其它导入的模块、模块级的变量和常量。局部名称(local names),函数中定义的名称,记录了函数的变量,包括函数的参数和局部定义的变量。(类中定义的也是)命名空间的查找顺序:L-----G-------B
命名空间的生命周期:
命名空间的生命周期取决于对象的作用域,如果对象执行完成,则该命名空间的生命周期就结束。
因此,我们无法从外部命名空间访问内部命名空间的对象。
作用域就是一个 Python 程序可以直接访问命名空间的正文区域。(就是访问命名空间的区域)
在一个 python 程序中,直接访问一个变量,会从内到外依次访问所有的作用域直到找到,否则会报未定义的错误。
Python 中,程序的变量并不是在哪个位置都可以访问的,访问权限决定于这个变量是在哪里赋值的。
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。Python的作用域一共有4种,分别是:
有四种作用域:
L(Local):最内层,包含局部变量,比如一个函数/方法内部。E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。G(Global):当前脚本的最外层,比如当前模块的全局变量。B(Built-in): 包含了内建的变量/关键字等。,最后被搜索作用域的查找顺序:L---E---G----B
作用域和命名空间的关系:某个作用域内命名和值之间的关系。作用域定义了命名空间的变量在多大的范围会起作用。
说明特征:
全局作用域中的代码不能使用任何局部变量;局部作用域可以访问全局变量;一个函数的局部作用域中的代码,不能使用其他局部作用域中的变量;如果在不同的作用域中,可以用相同的名字命名不同的变量。 var=1 #全局变量 G def index(): var1=2 #局部变量 L print(var1) index()global语句
当要进行写修改操作的时候,局部变量是对局部变量修改不了的。可以使用global关键字来声名它为全局变量。
var=1 def index(): global var #定义var为全局变量 var=2 print(var) index() print(var)
总结:全局变量和局部变量都对应的全局作用域和局部作用域。他们都有各自的命名空间。局部与局部的变量不能访问。就像个单项止回阀。
说明:
可变对象:list ,dict, set
不可变对象:str int tuple, float
>>> a=2 >>> b=2 >>> id(a) 140708589995712 >>> id(b) 140708589995712当数值从0-257过后id会变化。
>>> a='你好啊' >>> b='你好啊' >>> id(a) 2276918891312 >>> id(b) 2276918891408中文不一样
>>> x='xbl' >>> d='xbl' >>> id(x) 2276918955760 >>> id(d) 2276918955760字母一样
a=[1,2,3,4] print(id(a)) a.append(5) print(id(a))可变对象的添加id值不会变
浅复制和深复制
浅复制:
a=[1,2,3,4] b=a.copy() print((a),(b)) #对于可变对象浅赋值ID不同,会另外开辟一个空间 a.append(5) print(a,b) #浅赋值浅赋值其实只是赋值一次 a=[1,2,[3,4],5,[9,8]] b=a.copy() print(a,b) a.append(6) print(a,b) a[2].append(7) a[4].append(6) print(a,b) #对于列表里面存在子列表,子列表更改添加都会被复制过去总结:
对于可变的数据类型浅复制ID都不同,会开辟另外一个空间。浅复制其实就是值被复制了这一次,另外原本的在怎么改都和另外一个对象没有关系,除非里面有子级。浅复制子级更改添加都会影响到另外一个对象。深复制:
a=[1,2,[3,4]] b=copy.deepcopy(a) print(id(a),id(b)) #深复制是父级和子级全部拷贝过去,就算原始对象在怎么更改,另外一个对象都不会有任何反应 a.append(5) print(a,b) a[2].append(6) print(a,b)总结:
深复制其实就是单纯的复制了一次,以后原始对象在怎么改动都和另外一个对象无关。
说明:浅复制和深复制的差别在于可变对象里面的子对象,如果没有子对象其实都是一样的。就算复制过去复制过来,ID都是改变的。原始对象在怎么改变,另外一个对象除了子对象的差别其他没有任何不同
