最近在准备面试,回头看python基础的过程中,遇到一些小问题。
模块的搜索顺序是:
- 当前程序所在目录
- 当前程序根目录
- PYTHONPATH
- 标准库目录
- 第三方库目录site-packages目录
path 变量本质是一个列表,可以向path中添加模块所在的目录:sys.path.append('/Users/KG/Desktop')
import与from import的区别
- import方式
import 方式导入时,只是在当前文件中建立了一个模块的引用,通过模块的引用来使用模块内的数据 ,对文件内的数据,通过模块名都可以进行访问。可以将 import 导入方式理解成浅拷贝,只是拷贝了模块的一个引用,通过引用可以使用所有的数据 。
模块导入成功后,在使用模块过程中,如果被导入的模块对数据进行了修改,那么正在使用该模块的程序并不会修改。
就算重新导入修改后的模块也不行,因为程序在导入模块时,会将模块创建一个对象保存到一个字典中,如果之前导入过一次,再次导入时就不会再创建这个对象。
可以通过 sys 模块下的 modules 属性来查看一个文件中导入过的模块。
解决办法:使用 imp 模块下的 reload 函数重新加载模块
from imp import reload
reload(被修改的模块名)
一个疑问? ☞ import既然是浅拷贝,那为什么原模块的内容发生改变,正在使用该模块的程序不会改变呢?这不是和浅拷贝矛盾吗?!如果是我哪里的思路错误,希望指出。
我在pycharm中进行了实验,发现:原模块中内容发生改变,正在使用该模块的程序依然可以拿到最新的内容,即实时更新;
aa模块,如图:
运行bb.py:
改变aa模块内容:
再次运行bb.py
然后又在终端中进行了尝试,发现了上文所说的现象:
aa模块内容:
终端import导入,进行测试:
改变aa模块源文件内容:
重新导入,没有解决:
使用reload:
- from-import 方式
from-import 方式在导入数据时,会将导入模块中数据复制一份到当前文件中,所以可以直接使用模块中的变量,函数,类等内容。
from-import 方式可以理解成深拷贝,被导入模块中的数据被拷贝了一份放在当前文件中。
注意:
1、在使用 from-import 方式导入时,文件内私有属性 _xxx 形式的数据不会被导入。
只有x可以使用,私有属性_y和__z无法使用
2、在使用 from-import 方式导入时,如果模块内和当前文件中有标识符命名重名,会引用命名冲突,当前文件中的内容会覆盖模块的数据
要使用私有属性怎么办?
解决办法:
使用__all__ 魔法变量
如果模块中存在__all__这个变量,那么就按这个变量里的内容进行导入,没有包含的不导入。
如图:
使用哪种方式导入,需要根据实际情况考虑,从使用便利的角度,使用from-import,
从命名冲突的角度,使用 import。