Python 模塊與包

最近在自己自定義的包中相互引用文件時遇到不少問題,以前對包的瞭解不深,只是停留在會簡單調用,但是自己構建的時候才發現問題沒那麼簡單,於是便記錄梳理一下

在查閱資料之前,明確了有以下幾個問題:

  1. 包與模塊的區別
  2. 自定義的包,之間如何導入

包與模塊

我的理解:
包(Package):包含__init__.py的文件夾都可以視爲包
模塊(Module):以.py結尾的文件都可以視爲模塊

from package import *

F:\>  tree
mypackage
    - A
        - __init__.py(空)
    - B
        - __init__.py(空)
    - __init__.py(空)

新建項目結構如上

# 在F:\目錄啓動命令行,執行ipython
[In1]: from mypackage import *
[In2]: dir()
[Out2]: [
...     
]

當__init__.py文件爲空時, 以”*”導入mypackage下的模塊,A、B是不會被導入的

# mypackage/__init__.py
# 添加一下代碼
__all__=["A","B"]

保存後重啓命令行,再次執行導入

[In1]: from mypackage import *
[In2]: dir()
[Out2]: [
...
"A",
"B",
...     
]

此時使用“*”這種導入方式,會將__init__.py中__all___的內容導入,也就是說要想將mypackage包下的子包或模塊導入,需要在__all__變量中添加

from ./.. import module/class/variable

mypackage
│   banana.py
│   __init__.py
│
├───A
│   │   apple.py
│   │   __init__.py
│   
├───B
    │   mango.py
    │   orange.py
    │   __init__.py
# A\apple.py
class Apple():
    description = "I'm apple!"
# B\mango.py
class Mango():
    description = "I'm a mongo!"
# B\orange.py
from ..A.apple import Apple
from . import mango

fruit1 = Apple()
fruit2 = mango.Mango()
print(fruit1.description)
print(fruit2.description)

自定義包內相互調用方式

同級目錄下調用

導入方式
from . import module
from .module import class
from .module import variable

跨目錄調用

導入方式
from .. import package
from ..module import class/variable
from ..package import module
from ..package.module import class/variable

from . 相當於在此文件的目錄下查找
from .. 相當於在此目錄的上一級去查找

F:\> ipython
[In1]: from mypackage.B.orange import fruit1, fruit2
[In2]: fruit1.description
[Out2]: 
"I'm apple!"
[In3]: fruit2.description
[Out3]:
"I'm mango!"

注意:此種調用方式只能在包中使用,且只有在不主動使用時纔有效,不然會報錯,原因是:“.”,“..”這種方式是使用相對路徑去尋找的,只有當在包外面調用時才成立,如果直接運行(比如:orange.py)帶有“.”, “..”的.py文件,此時運行空間是相對文件自身的,所以相對路徑是不成立的。也就是說帶有’.’的.py文件需要在相對此文件目錄的上一級(mypackage)才能使用,當前目錄(B)是運行不了的,同理,“..”,需要在相對此文件目錄的上兩級的(mypackage外)才能使用
簡單來講:“.”是在文件目錄下的,相對路徑的表達方式才生效,文件本身是沒有“.”

記住一點就好:帶有“.”,“..”的.py文件不能以python filename.py這種方式運行

總結:需要手動運行的文件中,不要使用相對路徑(“.”“..”)的導入方式,相對路徑只建議在包中使用

發佈了35 篇原創文章 · 獲贊 7 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章