0

python 中 import 介绍

 2 years ago
source link: https://xujinzh.github.io/2022/04/27/python-import-and-run/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

python 中 import 介绍

发表于

2022-04-27 分类于 technologypython

阅读次数: 8 本文字数: 3.4k 阅读时长 ≈ 3 分钟

Python 中从其他模块或库中导入方法或模块的方法是利用 import 关键字,但是,当工程比较复杂时,比如分成多个类别的库;当代码需要在 jupyter 中调用工程中的模块时,工程中各模块的互相引用就显得非常重要,如果导入模块的姿势不对,将导致程序无法运行。本篇总结常用的导入方法,对 import 关键字进行介绍。

import 常规的导入方法这里不再重复,直接介绍复杂工程中或多种运行方式(命令行、ipython、jupyter 等)下模块的导入。

我这里创建了一个测试工程,目录结构如下:

$ tree mytest
mytest
├── p1
│   ├── __init__.py
│   └── q1.py
└── p2
├── __init__.py
├── q2.py
├── q3.py
└── q4.py

2 directories, 6 files

其中,mytest 是工程名字,p1 和 p2 分别是两个库,里面分别有模块 q1,q2 和 q3,这里给出他们的内容:

$ cat mytest/p1/q1.py
def add(x, y):
return x + y


$ cat mytest/p2/__init__.py
import os
PROJECT_PATH = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))


$ cat mytest/p2/q2.py
import sys
from . import PROJECT_PATH
sys.path.insert(0, PROJECT_PATH)
from p1 import q1
z = q1.add(2, 3)
print(z)


$ cat mytest/p2/q3.py
import sys
print(sys.path)
from p1 import q1
z = q1.add(2, 3)
print(z)


$ cat mytest/p2/q4.py
from .. import p1
z = p1.q1.add(2, 3)
print(z)

请查看 mytest/p1/q1.pymytest/p2/q3.py,在 q3 中导入了上一层目录 p1 里面的 q1 模块,使用该模块的 add 方法。属于绝对导入,这种方法以工程名所在目录为家目录,使用时必须保证 mytest 在 python 运行时的环境变量中。

请查看 mytest/p1/q1.pymytest/p2/q2.py,在 q2 中导入了上一层目录 p1 里面的 q1 模块,使用该模块的 add 方法。在使用绝对导入前,增加了相对导入 from . import PROJECT_PATH,使用动态的方式,将环境变量 mytest 在每次调用模块 q2 是添加到 python 环境变量中。

查看环境变量的方法:

import sys
sys.path

命令行运行

此时,想要运行 q3.py,可使用如下方法:

cd mytest
python -m p2.q3
5

该方法的更多信息请查看另一篇文章:在命令行运行 python 程序的方法

注意,此时使用如下方法,将会报错:

python p2/q3.py

因为此方法以 q3.py 所在目录为主目录:'/home/jinzhongxu/PythonProjects/mytest/p2',运行时将该目录添加到 sys.path 中,但这与 q3.py 中的模块导入 from p1 import q1 不符,因为 p1 不在被访问到,它不在 p2 目录下。但,python -m p2.q3 会将 '/home/jinzhongxu/PythonProjects/mytest' 作为主目录,运行时将该目录添加到 sys.path 中,因此,在 q3.py 中能够使用 模块导入 from p1 import q1.

运行 q2.py

cd mytest
$ python -m p2.q2
5

但如下方法将会报错:

cd mytest
$ python p2/q2.py
Traceback (most recent call last):
File "/home/jinzhongxu/PythonProjects/mytest/p2/q2.py", line 2, in <module>
from . import PROJECT_PATH
ImportError: attempted relative import with no known parent package

ipython 调用

如果运行方法如下,则同样能够通过:

cd mytest
$ ipython
Python 3.9.5 (default, Jun 4 2021, 12:28:51)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.30.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from p2 import q2
5

In [2]: from p2 import q3
['/home/jinzhongxu/PythonProjects/mytest', ...]
5

可以看到,该方法同样会将 '/home/jinzhongxu/PythonProjects/mytest' 添加到 sys.path 中。

jupyter 调用

如果想在 jupyter 中随处都调用 p2/q2.pyp2/q3.py,一种可行的方法是将 '/home/jinzhongxu/PythonProjects/mytest' 添加到环境变量中,此方法可参考:在 Python 中导入自己编写的模块,此时,在 jupyter 中调用方法如下:

from p2 import q2
from p2 import q3

如果添加的是 '/home/jinzhongxu/PythonProjects' 到 module.pth 中,那么 from p2 import q3 方法将失效,因为 mytest 不在 sys.path 中,但 from p2 import q2 确定正常执行,因为,模块 q2.py 会在程序运行时动态导入 mytestsys.path 中。

请查看 mytest/p1/q1.pymytest/p2/q4.py,在 q4 中导入了上一层目录 p1 里面的 q1 模块,使用该模块的 add 方法。属于相对导入。

命令行运行

cd mytest
python -m p2.q4
cd mytest
python p2/q4.py

ipython 调用

$ ipython
Python 3.9.5 (default, Jun 4 2021, 12:28:51)
Type 'copyright', 'credits' or 'license' for more information
IPython 7.30.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: from p2 import q4
---------------------------------------------------------------------------
ImportError Traceback (most recent call last)
<ipython-input-1-848272f17660> in <module>
----> 1 from p2 import q4

~/PythonProjects/mytest/p2/q4.py in <module>
1
----> 2 from .. import p1
3
4 z = p1.q1.add(2, 3)
5 print(z)

jupyter 调用

同样会报错。

当代码只在命令行中运行时,可简单的采用 q3.py 的模式。运行方法采用 python -m q3.py.

当代码不仅需要在命令行中运行,还需要再 jupyter 中调用时,配置环境变量很重要,推荐采用 q2.py 的模式。

尽量不要使用相对导入。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK