python3 包的导入和使用

__init__.py是个什么鬼?
# aaa/__init__.py
print(__name__)
num = 10

 

# a.py
import aaa


print(aaa.num)

执行a.py的结果:

aaa
10

 包的本质就是文件夹,导入包就相当于导入包下的__init__.py文件

 

看个复杂的包的使用(这种导入包的方式不推荐)

# a.py
import os

os.makedirs('glance/api')  # 创建目录
os.makedirs('glance/cmd')
os.makedirs('glance/db')
init_lst = ['glance/__init__.py', 'glance/api/__init__.py', 'glance/cmd/__init__.py', 'glance/db/__init__.py']
for initFile in init_lst:  # 创建文件并写入内容
    with open(initFile, "w", encoding="utf-8") as f:
        f.write(f"""#{initFile}""")

file_lst = ['glance/api/versions.py', 'glance/cmd/manage.py', 'glance/db/models.py', 'glance/api/policy.py']
for filePath in file_lst:
    with open(filePath, "w", encoding="utf-8") as f:  # 创建文件并写入内容
        f.write(f"""# {filePath}
def func():
    print("我在{filePath}中")""")

 

执行这个a.py文件,会创建一个glance文件夹,里面有三个文件夹api、cmd 和db,有几个py文件。

 

import 包(不推荐使用,很容易出现模块找不到的情况哦!)
# b.py
import glance glance.api.policy.func()

执行 b.py的结果:

Traceback (most recent call last):
  File "G:/python28/code/day06/整理笔记/python模块的使用/b.py", line 5, in <module>
    glance.api.policy.func()
AttributeError: module 'glance' has no attribute 'api'

原因分析:

因为import glance实际上是导入的glance/__init__.py,因为glance/__init__.py是个空文件,并没有api包的导入,所以报错。

 

解决这个报错

#glance/__init__.py
import glance.api

执行结果:

Traceback (most recent call last):
  File "G:/python28/code/day06/整理笔记/python模块的使用/b.py", line 5, in <module>
    glance.api.policy.func()
AttributeError: module 'glance.api' has no attribute 'policy'

依然报错,接着按照上面的处理方法处理:

 

#glance/api/__init__.py
import glance.api.policy

执行glance/api/__init__.py的结果:

我在glance/api/policy.py中

正常了,但是这个解决办法太麻烦了,需要在每个包的__init__.py文件中做包和模块的导入。正确导入包的方法看下面的代码。

 

from 包 import 模块(推荐使用)
from 包.包 import 模块(推荐使用)
# b.py
from glance.api import policy


policy.func()

执行b.py的结果:

我在glance/api/policy.py中

 

首先确认下,刚刚执行的py文件,是和glance同级的b.py文件。如果在glance/api/policy.py文件中调用glance/cmd/manage.py中的方法,怎么操作呐?我把glance目录里所有的__init__.py文件的内容都清空。

# glance/api/policy.py
from ..cmd import manage


def func():
    print("我在glance/api/policy.py中")

manage.func()

执行glance/api/policy.py的结果:

Traceback (most recent call last):
  File "G:/python28/code/day06/整理笔记/python模块的使用/glance/api/policy.py", line 2, in <module>
    from ..cmd import manage
ValueError: attempted relative import beyond top-level package

报错了,这个报错一定要记住,意思是不能超过当前py文件所在包的范围。那应该怎么解决呐?

 

# glance/api/policy.py
from glance.cmd import manage


def func():
    print("我在glance/api/policy.py中")

manage.func()

执行glance/api/policy.py结果:

我在glance/cmd/manage.py中

为什么这种方式导入包和模块就不报错了呐?看下面的程序,你就知道答案了。

 

# glance/api/policy.py
import sys
from glance.cmd import manage


def func():
    print("我在glance/api/policy.py中")


manage.func()
for path in sys.path:
    print(path)

执行glance/api/policy.py结果:

G:\python28\code\day06\整理笔记\python模块的使用\glance\api
G:\python28\code
G:\python28\code\day06\整理笔记\python模块的使用
D:\Program Files\JetBrains\PyCharm 2019.1\helpers\pycharm_display
G:\python3.6\python36.zip
G:\python3.6\DLLs
G:\python3.6\lib
G:\python3.6
G:\python3.6\lib\site-packages
G:\python3.6\lib\site-packages\win32
G:\python3.6\lib\site-packages\win32\lib
G:\python3.6\lib\site-packages\Pythonwin
D:\Program Files\JetBrains\PyCharm 2019.1\helpers\pycharm_matplotlib_backend

上面打印的是环境变量,重点是看第3条结果,因为在第3条的基础上是可以直接导入glance包的,第一条是当前py文件所在的目录。

 

总结:

在包内启动的时候,尽量不要使用相对路径。

尽量在包外启动。

 

posted on 2019-12-04 16:37  lilyxiaoyy  阅读(2726)  评论(0编辑  收藏  举报

返回
顶部