【python】import问题总结

一、绝对引用

首先总结一下import的各种姿势:

1、import package 读这个包的__init__.py

2、import module 读这个模块全部内容

3、import package1.package2.package3.module4 读package1, package2, package3的__init__.py, 以及module4全部内容(顺序)

4、import package1.package2 读 package1, package2的__init__.py(顺序)

这些是import中发生的事情。情况1、2没什么好说的,直接用package.或者module.就可以了。

情况3中,假设package1下有package2, package22, package222三个包,还有一个module2222模块,你想访问除了package2之外的其他东西,如果在所有的__init__.py中没有引用他们,那么调用是会出错的。

在情况3中,sys.modules会加入以下的模块

'package1'

'package1.package2'

'package1.package2.package3'

'package1.package2.package3.module4'

你尝试着看package1,或者调用package1.abc (abc在__init__中定义),这是可以成功的。

接着上面情况3的例子,现在你用

from package1.package2.package3 import module4

与之前一样,这些包的__init__也会运行

sys.modules与上述也相同

但是!神奇的地方来了!package1和package1.abc解释器并不认识!

原因是什么呢?猜测系统的逻辑如下:

import 1.2.3.4 那么你可能会用到1, 1.2, 1.2.3, 1.2.3.4, 系统默认都记下来

from 1.2.3 import 4,那么看起来你只会用到4, 那么1干脆就忘掉算了。但是1确实是跑过的,计算的东西都有,只不过并没有1并没有

绝对引用中的问题

import x1.x2报错找不到? 

每次Import x1.xxx的时候,都是要读x1.__init__.py的,如果没有该文件,那么就无法导入啦。

所以,如果第一层是个文件夹,一定要保证这个文件夹中有__init__.py文件!否则既不能import x1.x2, 也不能from x1 import x2。总之你就是无法得到x2,除非把x1加入到python环境变量PYTHONPATH中。

二、相对引用

从点和两点开始的引用,都是相对引用。

我们把相对引用存在的文件叫引用模块,

相对引用注意事项

1、相对引用发生在package内部,引用模块那一级一定要有__init__.py

2、调用的脚本的位置一定要在package外,如果脚本在引用模块那一级,实际上是找不到上一级的东西的,会报错。

  ValueError: Attempted relative import in non-package。

3、使用相对引用的模块,不能直接作为脚本跑,否则会报错

  ValueError: Attempted relative import in non-package。

  解决方法一: import 该脚本

  解决方法二:python -m 该脚本,也类似import。

相对引用原理

stackoverflow中有解释:relative import依赖文件__name__,而如果跑那个脚本的话,文件名字就成了__main__,这样__package__会被设为None,而相对引用依赖__package__的值,就找不到相对引用的位置了,会报Non-package的错误,在命令行中可以用-m跑,意思是把它当作一个模块。

三、根据名称import

按道理使用__import__函数即可,python对此特意进行了封装,成为importlib.import_module函数

该函数如果使用相对引用,需要给package参数,package名称和sys.modules中的名称相同即可

原文地址:https://www.cnblogs.com/yesuuu/p/6077463.html