模块进阶
模块进阶
python的源代码按功能可分为两种
1.用于执行的文件
2.用于被导入当做模块的文件
模块查找顺序
1.先从内存中已经导入的模块中寻找(sys.moudle)
2.内置的模块(time等)
3.自定义模块(执行文件所在目录)
4.环境变量sys.path中找(PYTHONPATH环境变量,但是可以在代码中动态添加)
5.标准库路径(python安装的地方)
6.pth文件自定义路径(在python安装目录新增加mypath.pth文件)
模块重载
我们已经知道,模块导入只会执行一次模块的代码,虽然好处很多,但是我们就需要重新执行模块的代码怎么办呢?
from imp import reload
reload(zx)
reload()会重新执行模板文件,但不会建立新的模板对象,会在原来的的对象上修改
from模块导入和执行文件重名
首先优先使用的是执行文件定义的全局变量
执行文件a.py
from b import x,y,z,c
x=1
y=[1,2]
z={1:2}
print(x,y,z,c)
模块文件b.py
x="a"
y=['a','b']
z={'a':'b'}
c=2
print(x,y,z)
a ['a', 'b'] {'a': 'b'}
1 [1, 2] {1: 2} 2
from导入模块的属性作为全局变量
上面的c属性其实经过了一步这样的操作
c=b.c
这样其实就相当于在执行文件中自己创建了一个全局变量
__main__
每一个.py文件都相当于一个模块,当运行的当前的.py文件,也会生成一个模块对象,这个模块的名字为__main__
,然后运行当前文件的属性和方法,其实相当于默认带了当前模块对象这个前缀。
一个很好的例子
aaaa.py
import bbbb
zx="a"
print(bbbb.__name__)
if __name__ == '__main__':
pass
bbbb.py
zx="b"
print(__name__)
运行aaaa.py
bbbb
b
bbbb
__main__
a
从运行结果可以发现,只有当前运行的文件模块名为__main__
,其他模块的名字就是py文件的名称,同理可得,如果从bbbb中import aaaa
的话,是进不去if判断的,那个时候模块名就为aaaa了
dir()
如何查看模块的定义了哪些属性(全局名称空间)
使用dir()内置方法
默认查看当前的属性,参数可以为导入的模块对象
案例
可以看到只会打印出全局的属性,函数内部的局部名称空间属性不会打印
执行文件a.py
import bbbb
x=1
y=[1,2]
z={1:2}
def zx():
i=0
print(dir())
print(dir(bbbb))
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'bbbb', 'x', 'y', 'z', 'zx']
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'x', 'xx', 'y', 'z']
模块文件bbbb.py
x="a"
y=['a','b']
z={'a':'b'}
def xx():
xxx=10