模块和包是比类更高一级的代码封装和复用,通过把相似的代码组织在一起使用,可以大量的减少程序的耦合。对于每个模块都有所谓的内部和外部之分,从这种角度来看,模块很像一种类,模块内部的代码属于模块的私有成员,由模块控制,对外暴露接口给外部使用。
为了方便解释,使用spyder创建一个项目,模块的引用就可以很方便的在IPython端使用。
Python的模块在首次导入(import)时,模块就会编译成字节码,也就是pyc文件(python3.2以后就统一存放在__pycache__目录下)。模块会被作为一个实例,为其内部提供一个全局名字空间,在一次的session中,无论模块的源文件是否发生变化,已经初始化后的实例都不会发生变化。先创建一个module.py文件,放入下面代码。
导入模块:
修改module文件变成:
再次导入文件:
x并没有发生变化。
所以这里牵扯到Python的热更新问题了,标准库提供了importlib.reload方法解决这个问题,但是这个方案缺点在于它并不会递归的修改成员引用(当你模块的成员被其它变量引用时,引用成员并不会发生变化)
除此之外,还可以使用__name__获得模块自身的信息。在module模块添加:
运行本模块,此时__name__返回的是__main__,而直接导入module时会返回模块自身的名字。
如果模块里面有些信息,不希望外部看到,可以使用__all__明确指定哪些成员允许被导入。在module.py添加:
这样其它的成员便被隐藏了,和类的私有成员一样,这不是真正的意义权限设置,你还是有办法可以看的到。例如:
我们这样就可以看到了module的所有的名字空间。
领取专属 10元无门槛券
私享最新 技术干货