Skip to main content

模塊:

当解释器遇到 import 语句,如果模块在当前的搜索路径就会被导入。

搜索路径是一个解释器会先进行搜索的所有目录的列表。

一个模块只会被导入一次,不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。

模块的引入:

#把一个模块的所有内容全都导入到当前的命名空间
import module1[, module2[,... moduleN]]

#把模塊中的單個引用導入到命名空間
from modname import name1[, name2[, ... nameN]]

搜索路径

当你导入一个模块,Python 解析器对模块位置的搜索顺序是:

  • 当前目录
  • 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目录。
  • 如果都找不到,Python会察看默认路径。UNIX下,默认路径一般为/usr/local/lib/python/。

模块搜索路径存储在 system 模块的 sys.path 变量中。变量里包含当前目录,PYTHONPATH和由安装过程决定的默认目录。

PYTHONPATH 变量

作为环境变量,PYTHONPATH 由装在一个列表里的许多目录组成。PYTHONPATH 的语法和 shell 变量 PATH 的一样。

在 Windows 系统,典型的 PYTHONPATH 如下:

set PYTHONPATH=c:\python27\lib;

在 UNIX 系统,典型的 PYTHONPATH 如下:

set PYTHONPATH=/usr/local/lib/python

linux系統中手動安裝python的話可能需要手動導入pythonpath到環境變量中

命名空间

命名空间,即Namespace,也成为名称空间或名字空间,指的是从名字到对象的一个映射关系,类似于字典中的键值对,实际上,Python中很多命名空间的实现用的就是字典。

不同命名空间是相互独立的,没有任何关系的,所以同一个命名空间中不能有重名,但不同的命名空间是可以重名而没有任何影响。

命名空间的类型

Python命名空间按照变量定义的位置,可以划分为3类:

  • Built-in ,内置命名空间,python自带的内建命名空间,任何模块均可以访问,存放着内置的函数和异常。
  • Global ,全局命名空间,每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量。
  • Local ,局部命名空间,每个函数、类所拥有的命名空间,记录了函数、类中定义的所有变量。

一个对象的属性集合,也构成了一个命名空间。但通常使用objname.attrname的间接方式访问属性,而不是 直接访问 ,故不将其列入命名空间讨论。

  • 直接访问 :直接使用名字访问的方式,如name,这种方式尝试在名字空间中搜索名字name。
  • 间接访问 :使用形如objname.attrname的方式,即属性引用,这种方式不会在命名空间中搜索名字attrname,而是搜索名字objname,再访问其属性。

命名空间的生命周期

  • 内置命名空间在Python解释器启动时创建,解释器退出时销毁;
  • 全局命名空间在模块被解释器读入时创建,解释器退出时销毁;
  • 局部命名空间,这里要区分函数以及类定义:
    • 函数的局部命名空间,在函数调用时创建,函数返回结果或抛出异常时被销毁(每一个递归函数都拥有自己的命名空间);
    • 类定义的命名空间,在解释器读到类定义(class关键字)时创建,类定义结束后销毁。

作用域

作用域是针对命名空间而言,指命名空间在程序里的可应用范围。只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,代码块(例如if、for代码块)不会产生新的作用域。

用域分类:

  • L(Local):最内层,包含局部变量,比如一个函数/方法内部。
  • E(Enclosing):包含了非局部(non-local)也非全局(non-global)的变量。比如两个嵌套函数,一个函数(或类) A 里面又包含了一个函数 B ,那么对于 B 中的名称来说 A 中的作用域就为 nonlocal。
  • G(Global):当前脚本的最外层,比如当前模块的全局变量。
  • B(Built-in): 包含了内建的变量/关键字等,最后被搜索。

作用域规则顺序:

L->E->G->B 如果变量在局部内找不到,便会去局部外的局部找(例如闭包),再找不到就会去全局找,再找不到就去内置中找

全局变量和局部变量

局部变量只能在其被声明的函数内部访问,调用函数时,所有在函数内声明的变量名称都将被加入到作用域中。

全局变量可以在整个程序范围内访问。

变量访问顺序

当前作用域局部变量->外层作用域变量->再外层作用域变量->......->当前模块全局变量->pyhton内置变量

global 和 nonlocal关键字

  • global:全局变量,当局部作用域改变全局变量用global,同时global还可以定义新的全局变量
  • nonlocal:外层嵌套函数的变量,nonlocal不能定义新的外层函数变量,只能改变已有的外层函数变量,同时nonlocal不能改变全局变量
global num  # 需要使用 global 关键字声明
nonlocal num # nonlocal关键字声明,使用函数中变量,修飾后,上層函數可以訪問num

global 和 nonlocal 的区别

  • 两者的功能不同。global 关键字修饰变量后标识该变量是全局变量,对该变量进行修改就是修改全局变量,而 nonlocal 关键字修饰变量后标识该变量是上一级函数中的局部变量,如果上一级函数中不存在该局部变量,nonlocal 位置会发生错误(最上层的函数使用nonlocal修饰变量必定会报错)。
  • 两者使用的范围不同。global 关键字可以用在任何地方,包括最上层函数中和嵌套函数中,即使之前未定义该变量,global 修饰后也可以直接使用,而 nonlocal 关键字只能用于嵌套函数中,并且外层函数中定义了相应的局部变量,否则会发生错误

Python中的包

包是一个分层次的文件目录结构,它定义了一个由模块及子包,和子包下的子包等组成的 Python 的应用环境。

简单来说,包就是文件夹,但该文件夹下必须存在 init .py 文件, 该文件的内容可以为空。init.py 用于标识当前文件夹是一个包。