93 lines
3.1 KiB
Markdown
93 lines
3.1 KiB
Markdown
# python3小白课:包成员导入
|
||
|
||
### 包成员导入的一般方法
|
||
|
||
这部分讲的方法比较适用于在`__init__.py`文件中未做其他操作或者该文件为空的场景。
|
||
|
||
我们就拿上节课讲到的定义的`xiaobai`这个包来说起。
|
||
|
||
我们再回顾一下这几个文件的内容:
|
||
|
||
`module1.py`文件:
|
||
|
||
```python
|
||
# coding:utf-8
|
||
"""
|
||
我是module1
|
||
"""
|
||
NAME = "小白"
|
||
AGE = 18
|
||
```
|
||
|
||
`module2.py`文件:
|
||
|
||
```python
|
||
# coding:utf-8
|
||
"""
|
||
我是module2
|
||
"""
|
||
def add_1(num):
|
||
return num + 1
|
||
```
|
||
|
||
基于上述内容我们有如下一些说明的导入用例,用于写在`test.py`文件中(它不是一个可用用例,只是为了解释说明一些导入的方法):
|
||
|
||
```python
|
||
# coding:utf-8
|
||
# 直接导入xiaobai包,实际上就是导入__init__.py文件
|
||
import xiaobai
|
||
# 可以导入包中的子模块,如果未指定别名,使用时需要用导入的这么一长串来作为调用前缀
|
||
import xiaobai.module1
|
||
# 这种方式导入子模块,调用时前缀能稍微短一点
|
||
from xiaobai import module1
|
||
# 也可以导入某个模块的成员进来,可以不用前缀直接使用
|
||
from xiaobai.module2 import add_1
|
||
```
|
||
|
||
通过上述几个,相信你已经有了举一反三的能力,获取对应包的成员或对应包的导入也就不在话下了。我们注意到,这其中的关健就是`.`这个符号,这个符号能够进入更深的包层级,有了它,即使你有更深层级的子包定义也能顺利导入了。
|
||
|
||
---
|
||
|
||
### 通过\_\_init\_\_.py文件整合包成员
|
||
|
||
因为写导入包本身的本质就是会执行`__init__.py`文件,所以包内的子模块的成员,我们可以在这个文件中编写导入。
|
||
|
||
我们说一下常见的两种写法的区别(下述不是真正可用的文件代码):
|
||
|
||
```python
|
||
# coding:utf-8
|
||
# .表示当前模块,这种写法的话相当于将模块导入包名中,调用时依然还是需要使用长长的方式调用
|
||
# 比如在__init__.py中这样写导入(该文件不能直接自执行,只能被导入,否则会报错):
|
||
from . import module1
|
||
# test.py中调用时要这样写:
|
||
import xiaobai
|
||
print(xiaobai.module1.NAME)
|
||
# 上述写法很长,我们可以写成这样,在__init__.py文件中:
|
||
from .module1 import *
|
||
# 这样在外部就可以用xiaobai前缀来调用module1的全部成员了,在test.py中:
|
||
import xiaobai
|
||
print(xiaobai.NAME)
|
||
```
|
||
|
||
基于前面讲的内容,我们这会儿来补充一下`__init__.py`文件的内容如下:
|
||
|
||
```python
|
||
# coding:utf-8
|
||
from .module1 import *
|
||
from .module2 import *
|
||
```
|
||
|
||
然后可以在`test.py`文件中这样写来方便调用:
|
||
|
||
```python
|
||
# coding:utf-8
|
||
import xiaobai
|
||
print(xiaobai.NAME, xiaobai.AGE)
|
||
print(xiaobai.add_1(100))
|
||
```
|
||
|
||
这样可以实现在包中方便管理代码,在外部调用时也调用方便。
|
||
|
||
> [!tip]
|
||
>
|
||
> 上述写法比较适用于多个子模块之间没有重名的情况,如果有重名的情况,可能会存在某些成员被覆盖等问题,具体你可以自行测试一下。起名时尽量不要重名,如果非要重名,可以使用之前讲过的导入子模块的方式,而不在初始化文件中做导入。 |