天天看點

15.包

目錄

  • 1.什麼是包?
  • 2.為何要使用包
  • 3.注意事項
  • 4.包的使用
    • 4.1 導入包與__init__.py
      • 4.1.2 import和from ... import ...
      • 4.1.3 絕對導入與相對導入
      • 4.1.4 from 包 import *

#官網解釋
Packages are a way of structuring Python’s module namespace by using “dotted module names”
包是一種通過使用‘.子產品名’來組織python子產品名稱空間的方式。

#具體的:包就是一個包含有__init__.py檔案的檔案夾,是以其實我們建立包的目的就是為了用檔案夾将檔案/子產品組織起來

#需要強調的是:
  1. 在python3中,即使包下沒有__init__.py檔案,import 包仍然不會報錯,而在python2中,包下一定要有該檔案,否則import 包報錯

  2. 建立包的目的不是為了運作,而是被導入使用,記住,包隻是子產品的一種形式而已,包的本質就是一種子產品
           

包的本質就是一個檔案夾,那麼檔案夾唯一的功能就是将檔案組織起來
随着功能越寫越多,我們無法将是以功能都放到一個檔案中,于是我們使用子產品去組織功能,而随着子產品越來越多,我們就需要用檔案夾将子產品檔案組織起來,以此來提高程式的結構性和可維護性
           

#1.關于包相關的導入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什麼位置,在導入時都必須遵循一個原則:凡是在導入時帶點的,點的左邊都必須是一個包,否則非法。可以帶有一連串的點,如item.subitem.subsubitem,但都必須遵循這個原則。但對于導入後,在使用時就沒有這種限制了,點的左邊可以是包,子產品,函數,類(它們都可以用點的方式調用自己的屬性)。

#2、import導入檔案時,産生名稱空間中的名字來源于檔案,import 包,産生的名稱空間的名字同樣來源于檔案,即包下的__init__.py,導入包本質就是在導入該檔案

#3、包A和包B下有同名子產品也不會沖突,如A.a與B.a來自倆個命名空間
           

例:

pool/                #頂級包
├── __init__.py     
├── futures          #子包
│   ├── __init__.py
│   ├── process.py
│   └── thread.py
└── versions.py      #子子產品
           

包屬于子產品的一種,因而包以及包内的子產品均是用來被導入使用的,而絕非被直接執行,首次導入包(如import pool)同樣會做三件事:

1、執行包下的__init__.py檔案

2、産生一個新的名稱空間用于存放__init__.py執行過程中産生的名字

3、在目前執行檔案所在的名稱空間中得到一個名字pool,該名字指向__init__.py的名稱空間,例如http://pool.xxx和pool.yyy中的xxx和yyy都是來自于pool下的__init__.py,也就是說導入包時并不會導入包下所有的子子產品與子包

1 關于包相關的導入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什麼位置,在導入時都必須遵循一個原則:凡是在導入時帶點的,點的左邊都必須是一個包,否則非法。可以帶有一連串的點,如import 頂級包.子包.子子產品,但都必須遵循這個原則。但對于導入後,在使用時就沒有這種限制了,點的左邊可以是包,子產品,函數,類(它們都可以用點的方式調用自己的屬性)。

2、包A和包B下有同名子產品也不會沖突,如A.a與B.a來自倆個命名空間

3、import導入檔案時,産生名稱空間中的名字來源于檔案,import 包,産生的名稱空間的名字同樣來源于檔案,即包下的__init__.py,導入包本質就是在導入該檔案

針對包内的子產品之間互相導入,導入的方式有兩種

1、絕對導入:以頂級包為起始

#pool下的__init__.py
from pool import versions
           

2、相對導入:.代表目前檔案所在的目錄,..代表目前目錄的上一級目錄,依此類推

#pool下的__init__.py
from . import versions
           

針對包内部子產品之間的互相導入推薦使用相對導入,需要特别強調:

1、相對導入隻能在包内部使用,用相對導入不同目錄下的子產品是非法的

2、無論是import還是from-import,但凡是在導入時帶點的,點的左邊必須是包,否則文法錯誤

#futures下的__init__.py
__all__=['process','thread']