python小知識點4 --import和__init__的作用和使用方法

文章截取自:python包的導入——__init__.py - CSDN博客  https://blog.csdn.net/zyl1042635242/article/details/44196601

                        Python包中__init__.py作用 - 徐文 - 博客園  http://www.cnblogs.com/AlwinXu/p/5598543.html

重要知識點:

1、__init__.py的主要作用是:

     1. Python中package的標識,不能刪除

             __init__.py的第一個作用就是package的標識,如果沒有該文件,該目錄就不會認爲是package。

     2. 定義__all__用來模糊導入

              模糊導入中的*中的模塊是由__all__來定義的,__init__.py的另外一個作用就是定義package中的__all__,用來模糊導入

2、package內部互相調用:import module_11

3、 package外部互相調用:

          方法一 、from 包名.模塊  import   函數名(funcA)

                           函數名也可以換成 * 號導入模塊(.py文件)中所有的函數,這條語句可以直接在包外使用。

                           這時可以直接調用  funcA()

           方法二、from 包名   import   模塊  

                           這條語句可以直接在包外使用。再使用語句  模塊.funcA()    來調用函數funcA 

           方法三、  __all__ = ["模塊1","模塊2",……]

                           只有這句話寫在__init__.py中 ,包外才能使用語句  from 包名 import *  進行模糊導入,然後在導入處使用語句                               模塊.funcA()  調用函數。

                           也可以使用from 包名.模塊  import * 此時__all__=["funcA","函數"……]  此時可以直接使用函數  funcA() ,但是                               不建議這樣使用,因爲如果有多個模塊都包含funcA函數,就會出現導入混亂。(如果出現這種情況,注意此時                                funcA 會執行最後一次import所導入的funcA函數)

 

 

 Python中常見的文件導入模式:

    其實,主要是用到Python的包的概念,而__init__.py在包裏起着重要作用。要弄明白這個問題,首先要知道,Python在執行import語句時,到底進行了什麼操作,按照python的文檔,它執行了如下操作:
    第1步,創建一個新的,空的module對象(它可能包含多個module)

    第2步,把這個module對象插入sys.module中
    第3步,裝載module的代碼(如果需要,首先必須編譯)
    第4步,執行新的module中對應的代碼。

    在執行第3步時,首先要找到module程序所在的位置。其原理爲:如果需要導入的module的名字是m1,則解釋器必須找到m1.py,它首先在當前目錄查找,然後是在環境變量PYTHONPATH中查找。PYTHONPATH可以視爲系統的PATH變量一類的東西,其中包含若干個目錄。如果PYTHONPATH沒有設定,或者找不到m1.py,則繼續搜索與Python的安裝設置相關的默認路徑。正因爲存在這樣的順序,如果當前路徑或PYTHONPATH中存在與標準module同樣的module,則會覆蓋標準module。也就是說,如果當前目錄下存在xml.py,那麼執行import xml時,導入的是當前目錄下的module,而不是系統標準的xml。

    瞭解了這些,我們就可以先構建一個package,以普通module的方式導入,就可以直接訪問此package中的各個module了。Python中的package定義很簡單,其層次結構與程序所在目錄的層次結構相同,這一點與Java類似,唯一不同的地方在於,python中的package必須包含一個__init__.py的文件。
例如,我們可以這樣組織一個package:

package1/
    __init__.py
    subPack1/
        __init__.py
        module_11.py
        module_12.py
        module_13.py
    subPack2/
        __init__.py
        module_21.py
        module_22.py
    ……
    __init__.py可以爲空,只要它存在,就表明此目錄應被作爲一個package處理。當然,__init__.py中也可以設置相應的內容,下文詳細介紹。好了,現在我們在module_11.py中定義一個函數:

def funA():
    print "funcA in module_11"
    return

    在頂層目錄(也就是package1所在的目錄,當然也參考上面的介紹,將package1放在解釋器能夠搜索到的地方)運行python:

>>>from package1.subPack1.module_11 import funcA
>>>funcA()
funcA in module_11

    這樣,我們就按照package的層次關係,正確調用了module_11中的函數。

    細心的用戶會發現,有時在import語句中會出現通配符*,導入某個module中的所有元素,這是怎麼實現的呢?
答案就在__init__.py中。我們在subPack1的__init__.py文件中寫

__all__ = ['module_13', 'module_12'] ,然後進入python

>>>from package1.subPack1 import *
>>>module_11.funcA()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_11

也就是說,以*導入時,package內的module是受__init__.py限制的。

    好了,最後來看看,如何在package內部互相調用。如果希望調用同一個package中的module,則直接import即可。也就是說,在module_12.py中,可以直接使用

import module_11

如果不在同一個package中,例如我們希望在module_21.py中調用module_11.py中的FuncA,則應該這樣:

from module_11包名.module_11 import funcA

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章