模块
- 模块是Python中最高级别的程序组织单元,它将程序代码和数据封装起来以便重用,而模块就对应Python中的程序文件(.py文件)
- 模块也是Python对象,具有随机的名字属性用来绑定或引用
- 模块能定义函数、类和变量。
- 模块里也能包含可执行的代码。
- 引入
- import:导入一个整体的模块
- from :从一个模块中获取一些特定的内容
- reload:在不中止Python程序的情况下,重新导入模块文件内容的方法
导入模块:import
语法:
import module[,module2[,…modulen]
- import导入整个模块内容
- 在当前路径搜索要导入的模块
- 一个模块只会被导入一次
- 模块中的内容是导入到模块的命名空间中的,访问模块中的方 法和属性时,必须使用模块名.方法名/属性名的格式
#test.py
def print_func(name):
return ('hello',str(name)
#demo.py
import test
print(test.print_func('china'))
导入模块:from… import …
语法
from modname import name1[, name2[,… nameN]]
- 从模块中导入一个指定的部分到当前命名空间中
- 导入到了当前.py文件命名空间中,直接访问函数名或属性名即可
- 同名的属性和方法,后引入的模块会覆盖先引入的模块中同名的内容
#a.py
b=1
def add(a):
a += 1
return a
class P():
print('hello,world')
#b.py
from a import b,add,p
print(P())
import 和 from… import … 区别
- import导入的是一整个模块,而from…import…导入的却是模块中某些特定的内 容
- import导入的内容是存放在模块命名空间中的,而from…import…却是存放在当前命名空间中的
- 使用import导入的模块,访问其中的属性与方法时,需要使用模块名.方法名(或 属性名等)
- 使用from…import…导入的模块,由于是导入到当前的命名空间中的,所以只需 要直接使用属性名或方法名即可
- 当导入的多个模块中含有同名方法或属性时,如果使用import导入,后导入的同 名方法或属性不会覆盖先导入的其他模块中的同名的方法或属性;如果使用 from…import…导入的,后导入的同名属性或方法会覆盖最先导入的其他模块中 的同名方法或属性
定位模块
- 当前目录
- PYTHONPATH: 如果不在当前目录,Python 则搜索在 shell 变量 PYTHONPATH 下的每个目
录,用sys.path.append来进行添加 - site-packages: 如果都找不到,python会查安装路径lib下的site-packages。Unix下,默认路
径一般是/usr/local/python/ - 模块搜索路径存储在system模块的sys.path变量中。变量里包含当前目录, PYTHONPATH由安装过程决定的默认目录。
命名空间
定义
名称到对象的映射。命名空间是一个字典的实现,键为变量名,值是变量对应的值。各个命名空间是独立没有关系的,一个命名空间中不能有重名,但是不同的命名空间可以重名而没有任何影响
分类
- 局部命名空间:每个函数所拥有的命名空间,记录了函数中定义的所有变量,包括函数的入参、内部定义的局部变量
- 全局命名空间:每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量
- 内建命名空间:任何模块均可以访问,放着内置的函数和异常
作用域
定义
作用域是针对变量而言,指申明的变量在程序里的可应用范围。或者称为变量的可见性
分类
- Local(函数内部)局部作用域
- Enclosing(嵌套函数的外层函数内部)嵌套作用域(闭包)
- Global(模块全局)全局作用域
- Built-in(内建)内建作用域
命名空间和作用域的关系
- 每个函数都有自己的命名空间
- 局部变量和一个全局变量重名,则局部变量会覆盖全局变量
- 任何在函数内赋值的变量都是局部变量
- 全局变量在函数里赋值,使用global 关键字
- 函数外的list变量在函数内部使用无需声明为global
Money=200
def addMoney():
global Money
Money += 1
print(Money)
addMoney()
print(Money)
包
包是一个分层的文件目录结构,它定义了一个由模块及子包和子 包下的子包等组成的Python的应用环境
- 需要包含 init.py 文件
- __all__的值:在from package-name import *这语句使用的,表示全部导出定义过的模块
#a.py
__all__ = ['bar','baz']
waz = 5
bar = 10
def baz():
return 'baz'
#b.py
from a import *
print(bar)
print(baz)
print(waz)
#name 'waz' is not defined
使用 import 和 from… import … 导入包
在包文件中的__init__文件中的__all__表示允许其他程 序使用from testmodule import *时可以导入 testmodule中的哪些模块,防止一次导入太多模块导 致名称冲突
# module a.py
# module b.py
# module __init__.py
__all__ = ['a']
#b.py
from module import a
#d.py
from . import *
包中创建子包
#moudle a.py
def add(a,b):
return a+b
#moudle/submoudle c.py
from math import sqrt,pow
def multiple(a,b):
return pow(2,3)
#b.py
import moudle.a
import moudle.submoudle.c
print(moudle.a.add(10,20))
print(moudle.submoudle.multiple(10,20))
包中添加路径
#test/a.py
def add(a,b):
return a+b
#test/b.py
def sub(a,b):
return a-b
#__init__.py
import sys
sys.path.append('./test')
from a import *
from b import *
#c.py
import test
test.add(1,2)
test.sub(2,1)
包的总结
- 第一次导入一个模块,会执行这个模块
- 可以通过修改模块module的__all__列表,来改变from module import * 时的效果
- 导入一个包,其实就是导入包的__init__.py模块
- 如果包的__init__.py模块为空,那么import package这样的语句是不能使用包当中的任何模块的
- 如果包的__init__.py模块为空,那我们只能使用import package.module或者from package import module这样的导入方式
- init.py也是个模块,其实也可以在__init__.py中直接定义函数fun,那样import package就可以直接用package.fun这个函数了是吧。但是我们一般不会这么干,这样会使__init__.py文件太乱
- init.py也是个模块,那也可以在这个模块中导入其他模块,这样importpackage时,就能直接使用一些符号了。
- init.py也是个模块,也可以定义__all__列表变量,控制from package
import * 的作用。