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文件所在的目錄。

 

總結:

在包內啟動的時候,盡量不要使用相對路徑。

盡量在包外啟動。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM