一、模塊和包:python
咱們今天來說解一下模塊和包,模塊咱們已經知道是什麼東西了,咱們如今來看看這個包是個什麼? 我說的包可不是女同胞一看見就走不動的包,而是程序中一種組織文件的形式.api
只要文件夾下含有__init__.py文件就是一個包,包是幹什麼的呢?工具
回想一下,以前咱們沒有學習模塊的時候將一個總體的功能寫入到文件中,爲了可以充分的將某個功能進行重用 咱們使用了模塊,可是慢慢的模塊就會愈來愈多.咱們想提升程序的結構性可維護性,就使用包將模塊進行統一管理學習
包可以管理多個模塊,咱們想要使用包裏的模塊怎麼辦呢?測試
使用import 和from xx import xx 現有以下結構spa
bake
├── __init__.py ├── api ├── __init__.py ├── policy.py └── versions.py ├── cmd ├── __init__.py └── manage.py └── db ├── __init__.py └── models.py
咱們在bake同級建立一個test.py進行導入policy.py 咱們使用模塊的import的時候只能將api添加到sys.path的路勁中,咱們來看看包使用import導入code
import bake.api.policy bake.api.policy.get()
導入的太長了下邊使用的時候還須要在重複寫一遍,咱們可使用as起別名token
import bake.api.policy as p p.get()
這樣的操做只支持包,普通的文件夾無效,有人必定在想我把bake拿過來而後一層一層的打開那拿工具就能夠了get
import bake bake.api.policy.get()
很差使,這樣導入是隻將policy導入了,有人想怎麼將api包下的模塊所有導入不要急,先說單獨導入的方式cmd
我們可以使用import進行導入,在來看看from的導入方式
from bake.api import policy policy.get()
from bake import api print(api.versions.name)
仍是很差使,經過這兩個咱們可以感受都導入的時候指定要導入的內容,不能再導入後在進行開箱子
咱們如今說了單獨導入一個模塊,如今來講道說道怎麼導入某個包下的全部模塊,想要導入某個包下的全部的模塊 咱們就須要在包中的__init__.py作點手腳
bake包下的__init__.py from . import api
.是當前路徑,由於from的時候不能空着
api包下的__init__.py from . import policy
咱們將包下的__init__配置好,而後在test.py進行導入
import bake bake.api.policy.get()
又好使了,這是爲何呢?咱們import導入bake這個包,由於bake是一個文件夾不能進行任何操做,就讓__init__.py代替它 去將api這包中的模塊導入,api也是一個文件夾不能操做就須要讓api下邊的__init__.py去找api下邊的兩個模塊
這個和公司的上下級關係同樣,打比方如今test.py就是一個ceo要和policy這個小員工談話,ceo先把這個想法人事經理,人事經理就是 bake這個包,人事經理通知人事讓人事查找一下policy在那個部門,人事查到後通知部門的負責人,部門的負責人在通知部門的主管,主管告訴policy這個員工, 說ceo要找你,部門的主管帶着policy去找人事,人事帶着policy,人事而後在帶着policy去找ceo.最後成功的和ceo進行了一番交流
若是在傳達的時候中間一個環節忘記傳遞了,policy就不知道ceo在找他,ceo等了很久不來ceo就生氣報錯了
使用的時候須要注意: 有的同窗,想在policy文件中導入versions就是直接使用import,在policy文件使用沒有問題,很美,很高興.可是在test.py執行的時候就會報錯 由於咱們在test.py中執行的import versions 至關於在test.py文件進行查找,確定不會找到,咱們須要在policy文件中向sys.path添加了當前的路勁就能夠了 具體操做以下:
import os import sys sys.path.insert(os.path.dirname(__file__)
__file__獲取的是當前文件的路徑,這樣咱們就能在test中正常使用了,咱們使用from也可以將某個包下全部的模塊全都導入 好比咱們如今想將cmd包下的全部的模塊導入須要在bake包下的__init__.py進行設置
from . import *
咱們須要在api包下設置__init__.py
__all__ = ["policy","versions"] 或 from . import policy from . import versions
咱們須要在db包下設置__init__.py
__all__ = ["models"] 或 from . import models
咱們須要在cmd包下設置__init__.py
__all__ = ["manage"] 或 from . import manage
以上兩種推薦使用下from . import manage 靈活,可讀性高
test.py調用以下:
from bake.api import * print(versions.name) policy.get() from bake.db import * models.register_models(123) from bake.cmd import * print(manage.name)
在使用import有個注意點,python2中若是import包,沒有__init__.py文件就會報錯 python3 import沒有__init__.py文件的包不會報錯 from 包 import 包或者模塊(在import後邊不能在進行.操做)
路徑: 絕對路徑:從最外層(bake)包.查找的就是絕對路徑 相對路徑:.就是相對路徑, ..是上一級目錄 例如:咱們在bake/api/version.py中想要導入bake/cmd/manage.py
# 絕對路徑: from bake.cmd import manage manage.main() #相對路徑: from ..cmd import manage manage.main()
注意在使用相對路徑的時候必定要在於bake同級的文件中測試 咱們須要在和bake同級的test.py中測試
from bake.cmd import manage
做業題: