1. 程式人生 > >【python基礎】模組、包

【python基礎】模組、包

目錄

<4> as

1、什麼是模組

有過C語言程式設計經驗的朋友都知道在C語言中如果要引用sqrt函式,必須用語句#include <math.h>引入math.h這個標頭檔案,否則是無法正常進行呼叫的。

那麼在Python中,如果要引用一些其他的函式,該怎麼處理呢?

在Python中有一個概念叫做模組(module),這個和C語言中的標頭檔案以及Java中的包很類似,比如在Python中要呼叫sqrt函式,必須用import關鍵字引入math這個模組,下面就來了解一下Python中的模組。

說的通俗點:模組就好比是工具包,要想使用這個工具包中的工具(就好比函式),就需要匯入這個模組

2、如何匯入模組

<1>import

在Python中用關鍵字import來引入某個模組,比如要引用模組math,就可以在檔案最開始的地方用import math來引入。

形如:

    import module1,mudule2...

當直譯器遇到import語句,如果模組在當前的搜尋路徑就會被匯入。

在呼叫math模組中的函式時,必須這樣引用:

  模組名.函式名
  • 想一想:

    為什麼必須加上模組名呼叫呢?

  • 答:

    因為可能存在這樣一種情況:在多個模組中含有相同名稱的函式,此時如果只是通過函式名來呼叫,直譯器無法知道到底要呼叫哪個函式。所以如果像上述這樣引入模組的時候,呼叫函式必須加上模組名

    import math

    #這樣會報錯
    print sqrt(2)

    #這樣才能正確輸出結果
    print math.sqrt(2)
import time

time.sleep(1)
print("haha")

<2>from…import

語法如下:

    from modname import name1[, name2[, ... nameN]]

如:

# import time
# time.sleep(1)

from time import sleep,clock

sleep(1)  #此時不用帶上模組名,直接使用方法名或函式名
clock()
print("haha")

注意

  • 不會把整個time模組匯入到當前的名稱空間中,它只會將time裡的sleep,clock引入。
  • 通過這種方式引入的時候,呼叫函式時只能給出函式名,不能給出模組名,但是當兩個模組中含有相同名稱函式的時候,後面一次引入會覆蓋前一次引入。也就是說假如模組A中有函式function( ),在模組B中也有函式function( ),如果引入A中的function在先、B中的function在後,那麼當呼叫function函式的時候,是去執行模組B中的function函式。
  • 如果想一次性引入math中所有的東西,還可以通過from math import *來實現。

<3>from … import *

把一個模組的所有內容全都匯入到當前的名稱空間也是可行的,只需使用如下宣告:

    from modname import *

注意

  • 這提供了一個簡單的方法來匯入一個模組中的所有專案。然而這種宣告不該被過多地使用。

<4> as

可以理解成定義別名。

 import time as tt
# time.sleep(1)
# from time import sleep,clock
# 
# sleep(1)
# clock()
tt.sleep(1)
print("haha")

<5>定位模組

當你匯入一個模組,Python解析器對模組位置的搜尋順序是:

  1. 當前目錄
  2. 如果不在當前目錄,Python則搜尋在shell變數PYTHONPATH下的每個目錄。
  3. 如果都找不到,Python會察看預設路徑。UNIX下,預設路徑一般為/usr/local/lib/python/
  4. 模組搜尋路徑儲存在system模組的sys.path變數中。變數裡包含當前目錄,PYTHONPATH和由安裝過程決定的預設目錄。
In [1]: import os

In [2]: os.__file__
Out[2]: '/usr/local/python3.6/lib/python3.6/os.py'

##python的安裝路徑,自帶的模組都放在裡面

3、如何製作模組

<1>定義自己的模組

在Python中,每個Python檔案都可以作為一個模組,模組的名字就是檔案的名字。

比如有這樣一個檔案test.py,在test.py中定義了函式add

test.py


    def add(a,b):
        return a+b

<2>呼叫自己定義的模組

那麼在其他檔案中就可以先import test,然後通過test.add(a,b)來呼叫了,當然也可以通過from test import add來引入

main.py


    import test

    result = test.add(11,22)
    print(result)

<3>測試模組

在實際開中,當一個開發人員編寫完一個模組後,為了讓模組能夠在專案中達到想要的效果,這個開發人員會自行在py檔案中新增一些測試資訊,例如:

test.py


    def add(a,b):
        return a+b

    # 用來進行測試
    ret = add(12,22)
    print('int test.py file,,,,12+22=%d'%ret)

如果此時,在其他py檔案中引入了此檔案的話,想想看,測試的那段程式碼是否也會執行呢!

main.py


    import test

    result = test.add(11,22)
    print(result)

執行現象:

至此,可發現test.py中的測試程式碼,應該是單獨執行test.py檔案時才應該執行的,不應該是其他的檔案中引用而執行

為了解決這個問題,python在執行一個檔案時有個變數__name__

直接執行此檔案

在其他檔案中import此檔案

總結:

  • 可以根據__name__變數的結果能夠判斷出,是直接執行的python指令碼還是被引入執行的,從而能夠有選擇性的執行測試程式碼

4、模組中的__all__有什麼作用?

(1). 沒有__all__

(2). 模組中有__all__

總結

  • 如果一個檔案中有__all__變數,那麼也就意味著這個變數中的元素,不會被from xxx import *時匯入

5、包中__init__.py有什麼作用?

實際開發過程中會把有關聯的py放在一個資料夾裡面,組成一個包供程式呼叫,如何保證這個包能被使用呢?

1.1在msg資料夾下建立__init__.py檔案

1.2在__init__.py檔案中寫入

1.3重新使用from 資料夾 import 模組 的方式匯入

總結:

  • 包將有聯絡的模組組織在一起,即放到同一個資料夾下,並且在這個資料夾建立一個名字為__init__.py 檔案,那麼這個資料夾就稱之為
  • 有效避免模組名稱衝突問題,讓應用組織結構更加清晰

2.1. __init__.py檔案有什麼用

__init__.py 控制著包的匯入行為

2.2 __init__.py為空

僅僅是把這個包匯入,不會匯入包中的模組

2.3 __all__

__init__.py檔案中,定義一個__all__變數,它控制著 from 包名 import *時匯入的模組

2.4 (瞭解)可以在__init__.py檔案中編寫內容

可以在這個檔案中編寫語句,當匯入時,這些語句就會被執行

6、模組如何釋出

模組釋出

1.mymodule目錄結構體如下:

.
├── setup.py
├── suba
│   ├── aa.py
│   ├── bb.py
│   └── __init__.py
└── subb
    ├── cc.py
    ├── dd.py
    └── __init__.py

2.編輯setup.py檔案

py_modules需指明所需包含的py檔案,關鍵屬性是py_modules裡面  資料夾.檔名

from distutils.core import setup

setup(name="dongGe", version="1.0", description="dongGe's module", author="dongGe", py_modules=['suba.aa', 'suba.bb', 'subb.cc', 'subb.dd'])

3.構建模組

python setup.py build

構建後目錄結構

.
├── build
│   └── lib.linux-i686-2.7
│       ├── suba
│       │   ├── aa.py
│       │   ├── bb.py
│       │   └── __init__.py
│       └── subb
│           ├── cc.py
│           ├── dd.py
│           └── __init__.py
├── setup.py
├── suba
│   ├── aa.py
│   ├── bb.py
│   └── __init__.py
└── subb
    ├── cc.py
    ├── dd.py
    └── __init__.py

4.生成釋出壓縮包

python setup.py sdist

打包後,生成最終釋出壓縮包dongGe-1.0.tar.gz , 目錄結構

.
├── build
│   └── lib.linux-i686-2.7
│       ├── suba
│       │   ├── aa.py
│       │   ├── bb.py
│       │   └── __init__.py
│       └── subb
│           ├── cc.py
│           ├── dd.py
│           └── __init__.py
├── dist
│   └── dongGe-1.0.tar.gz
├── MANIFEST
├── setup.py
├── suba
│   ├── aa.py
│   ├── bb.py
│   └── __init__.py
└── subb
    ├── cc.py
    ├── dd.py
    └── __init__.py

7、模組安裝、使用

(1).安裝的方式

  1. 找到模組的壓縮包
  2. 解壓
  3. 進入資料夾
  4. 執行命令python setup.py install

注意:

  • 如果在install的時候,執行目錄安裝,可以使用python setup.py install --prefix=安裝路徑

(2).模組的引入

在程式中,使用from import 即可完成對安裝的模組使用

from 模組名 import 模組名或者*