python高級-模塊(14)

1、python中的模塊

有過C語言編程經驗的朋友都知道在C語言中若是要引用sqrt函數,必須用語句#include <math.h>引入math.h這個頭文件,不然是沒法正常進行調用的。python

那麼在Python中,若是要引用一些其餘的函數,該怎麼處理呢?程序員

在Python中有一個概念叫作模塊(module),這個和C語言中的頭文件以及Java中的包很相似,好比在Python中要調用sqrt函數,必須用import關鍵字引入math這個模塊,下面就來了解一下Python中的模塊。shell

說的通俗點:模塊就比如是工具包,要想使用這個工具包中的工具(就比如函數),就須要導入這個模塊編程

模塊的概念:app

  • 每個以擴展名py結尾的python源代碼文件都是一個模塊
  • 模塊名一樣也是一個標識符,須要符合標識符的命名規範
  • 在模塊中定義的全局變量、函數、類都是提供給外界直接使用的工具
  • 模塊就比如工具包,要想使用這個工具包中的工具,就須要先導入這個模塊

 

2、import

在Python中用關鍵字import來引入某個模塊,好比要引用模塊math,就能夠在文件最開始的地方用import math來引入。函數

import導入工具

import 模塊名1,模塊名2 #不推薦

說明:在導入模塊時,每一個導入應該獨佔一行(推薦)測試

import 模塊1 import 模塊2

導入以後ui

經過模塊名使用模塊提供的工具---全局變量、函數、類編碼

只用as指定模塊的別名

若是模塊的名字太長,可使用as指定模塊的別名,以方便在代碼中的使用

import 模塊名1 as 模塊別名

注意:模塊別名應該符合託峯值命名規範

爲何要加上模塊名呢?

由於可能存在這樣一種狀況:在多個模塊中含有相同名稱的函數,此時若是隻是經過函數名來調用,解釋器沒法知道到底要調用哪一個函數。因此若是像上述這樣引入模塊的時候,調用函數必須加上模塊名

 

3、from … import

from...import導入

  • 若是想從某一模塊中導入部分工具,就可使用from...import的方式
  • import模塊名是一次性把模塊中全部的工具所有導入,而且經過模塊名/別名訪問
#從模塊中導入某一個工具
from 模塊名 import 工具名#能夠經過as爲工具指定別名

導入以後

  • 不須要經過模塊名. 的方式使用模塊提供的工具
  • 能夠直接使用模塊提供的工具  --- 全局變量、函數、類

注意:

  • 若是兩個模塊,存在同名的函數,name後導入模塊的函數會覆蓋先導入的函數
  • 開發時import代碼應該統一寫在代碼的頂部,更容易及時發現衝突
  • 必定大仙衝突,可使用as關鍵字,給其中一個工具起一個別名

from...import *

#從模塊中導入全部工具
from 模塊名 import *

注意:

這種法師不推薦使用,由於函數重名並無任何的提示,出現問題很差排查

案例:

demo.py(自定義的模塊)

#全局變量
title = "模塊1"

#函數
def say_hello(): print("我是%s"%title) #
class Dog(object): pass

#
class Cat(object): pass

test.py中使用demo.py模塊

#導入模塊中的全部工具,同時爲模塊指定別名爲myTest
import demo as myTest #導入模塊中全部工具,不推薦,工具同名很差排查 #from...import *  #from...import導入模塊中的部分工具(Dog類)
from demo import Dog #爲導入工具Cat類指定別名Test_Cat,防止與其餘模塊中工具重名
from demo import Cat as Test_Cat myTest.say_hello() dog=Dog() cat=Test_Cat()

 

4、python模塊導入的搜索路徑

  • 程序的主目錄
  • PTYHONPATH目錄(若是已經進行了設置)
  • 標準鏈接庫目錄(通常在/usr/local/lib/python2.X/)
  • 任何的.pth文件的內容(若是存在的話).新功能,容許用戶把有效果的目錄添加到模塊搜索路徑中去 .pth後綴的文本文件中一行一行的地列出目錄。
  • 這四個組建組合起來就變成了sys.path了,
  • 當python import模塊的時候,就經過sys.path裏面的目錄列表下面去查找。
  • sys.path是python的搜索模塊的路徑集,是一個list。
  • 查看sys.path方法:
import sys print(sys.path)
['C:\\Users\\Se7eN_HOU\\Desktop\\Tools\\sublimetext3\\Sublime Text Build 3176 x86', 
'C:\\Program Files\\Python37\\python37.zip',
'C:\\Program Files\\Python37\\DLLs',
'C:\\Program Files\\Python37\\lib',
'C:\\Program Files\\Python37',
'C:\\Users\\Se7eN_HOU\\AppData\\Roaming\\Python\\Python37\\site-packages',
'C:\\Program Files\\Python37\\lib\\site-packages']

程序執行時導入模塊路徑

import sys #由於sys.path是一個列表,因此能夠在後面追加一個自定的模塊路徑
sys.path.append("/home/Se7eN_HOU") #經過insert能夠將路徑插到前面
sys.path.insert(0,"Home/Se7eN") print(sys.path)

運行結果爲:

['Home/Se7eN', 
'C:\\Users\\Se7eN_HOU\\Desktop\\Tools\\sublimetext3\\Sublime Text Build 3176 x86',
'C:\\Program Files\\Python37\\python37.zip', 'C:\\Program Files\\Python37\\DLLs',
'C:\\Program Files\\Python37\\lib', 'C:\\Program Files\\Python37',
'C:\\Users\\Se7eN_HOU\\AppData\\Roaming\\Python\\Python37\\site-packages',
'C:\\Program Files\\Python37\\lib\\site-packages',
'/home/Se7eN_HOU']

 

5、模塊製做

一、定義本身的模塊

在Python中,每一個Python文件均可以做爲一個模塊,模塊的名字就是文件的名字。

好比有這樣一個文件test.py,在test.py中定義了函數add

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

二、調用本身的模塊

那麼在demo.py文件中就能夠先import test,而後經過test.add(a,b)來調用了,固然也能夠經過from test import add來引入

import test result = test.add(1,2) print(result)

運行結果爲:3

三、測試模塊

在實際開中,當一個開發人員編寫完一個模塊後,爲了讓模塊可以在項目中達到想要的效果,這個開發人員會自行在py文件中添加一些測試信息,例如:test.py文件

def add(a,b): return a+b #用來測試
ret = add(11,22) print("in test.py 測試11+22 = %d"%ret)

若是此時,在demo.py文件中引入了此文件的話,想一想看,測試的那段代碼是否也會執行呢!

import test result = test.add(1,2) print(result)

運行結果爲:

in test.py 測試11+22 = 33
3

至此,可發現test.py中的測試代碼,應該是單獨執行test.py文件時才應該執行的,不該該是其餘的文件中引用而執行。爲了解決這個問題,python在執行一個文件時有個變量__name__

test.py文件中:

def add(a,b): return a+b #用來測試 #ret = add(11,22) #print("in test.py 測試11+22 = %d"%ret)
print("in test.py,__name__ is %s"%__name__)

運行結果爲:

in test.py,__name__ is __main__

在demo.py文件中導入test.py模塊運行爲

import test result = test.add(1,2) print(result)

運行結果爲:

in test.py,__name__ is test 3

能夠根據__name__變量的結果可以判斷出,是直接執行的python腳本仍是被引入執行的,從而可以有選擇性的執行測試代碼

test.py模塊中代碼改成:

def add(a,b): return a+b if __name__ == "__main__": ret = add(11,22) print("in test.py 測試11+22 = %d"%ret)

在test.py中運行結果爲:

in test.py 測試11+22 = 33

在demo.py中導入test.py模塊

import test result = test.add(1,2) print(result)

運行結果爲:3

這樣咱們在開中測試的代碼,就不會在其餘模塊中出現了。

 

6、模塊中的_ _all_ _

一、沒有_ _all_ _

test.py模塊

class Test(object): def test(self): print("---Test類中的test方法---") def test1(): print("---test1方法---") def test2(): print("---test2方法---")

在demo.py中導入test.py模塊

from test import * a = Test() a.test() test1() test2() 

運行結果爲:

---Test類中的test方法---
---test1方法---
---test2方法---

二、模塊中有_ _all_ _

test.py模塊

__all__ = ["Test","test1"] class Test(object): def test(self): print("---Test類中的test方法---") def test1(): print("---test1方法---") def test2(): print("---test2方法---")

demo.py模塊

from test import * a = Test() a.test() test1() test2() 

運行結果爲:

---Test類中的test方法---Traceback (most recent call last): ---test1方法--- File "C:\Users\Se7eN_HOU\Desktop\Tools\sublimetext3\Sublime Text Build 3176 x86\demo.py", line 5, in <module> test2() NameError: name 'test2' is not defined

若是一個文件中有__all__變量,那麼也就意味着只有這個變量中的元素,纔會被from xxx import *時導入

7、系統sys模塊介紹

sys是python自帶模塊,經常使用的函數有:

 

  • sys.argv: 實現從程序外部向程序傳遞參數。

  • sys.exit([arg]): 程序中間的退出,arg=0爲正常退出。

  • sys.getdefaultencoding(): 獲取系統當前編碼,通常默認爲ascii。

  • sys.setdefaultencoding(): 設置系統默認編碼,執行dir(sys)時不會看到這個方法,在解釋器中執行不經過,能夠先執行reload(sys),在執行 setdefaultencoding('utf8'),此時將系統默認編碼設置爲utf8。(見設置系統默認編碼 )

  • sys.getfilesystemencoding(): 獲取文件系統使用編碼方式,Windows下返回'mbcs',mac下返回'utf-8'.

  • sys.path: 獲取指定模塊搜索路徑的字符串集合,能夠將寫好的模塊放在獲得的某個路徑下,就能夠在程序中import時正確找到。

  • sys.platform: 獲取當前系統平臺。

一、sys.argv[]

sys.argv[]說白了就是一個從程序外部獲取參數的橋樑,這個「外部」很關鍵。由於咱們從外部取得的參數能夠是多個,因此得到的是一個列表(list),也就是說sys.argv其實能夠看做是一個列表,因此才能用[]提取其中的元素。其第一個元素是程序自己,隨後才依次是外部給予的參數。

下面咱們經過一個極簡單的test.py程序的運行結果來講明它的用法。

1 #test.py
2 
3 import sys
4 a=sys.argv[0]
5 print(a)

將test.py保存在c盤的根目錄下。

在程序中找到 ‘運行’->點擊->輸入"cmd"->回車鍵   進入控制檯命令窗口(以下圖),先輸入cd c:\   (做用是將命令路徑改到c盤根目錄),而後輸入test.py運行咱們剛剛寫的程序:

獲得的結果是C:\test.py,這就是0指代碼(即此.py程序)自己的意思。

而後咱們將代碼中0改成1 :

a=sys.argv[1]

保存後,再從控制檯窗口運行,此次咱們加上一個參數,輸入:test.py what

1 #test.py
2 import sys
3
4 a=sys.argv[1]
5 print(a)

運行結果是:

獲得的結果就是咱們輸入的參數what,看到這裏你是否是開始明白了呢。

那咱們再把代碼修改一下:

a=sys.argv[2:]

保存後,再從控制檯窗臺運行程序,此次多加幾個參數,以空格隔開:

test.py a b c d e f

獲得的結果爲[‘b’, ’c’, ’d’, ’e’, ’f’]

 應該大徹大悟了吧。Sys.argv[ ]其實就是一個列表,裏邊的項爲用戶輸入的參數,關鍵就是要明白這參數是從程序外部輸入的,而非代碼自己的什麼地方,要想看到它的效果就應該將程序保存了,從外部來運行程序並給出參數。

二、sys.path已經在上面講過了

三、sys.exit()

程序中間的退出, arg=0爲正常退出
通常狀況下執行到主程序末尾,解釋器自動退出,可是若是須要中途退出程序,能夠調用sys.exit函數,帶有一個可選的整數參數返回給調用它的程序,表示你能夠在主程序中捕獲對sys.exit的調用。(0是正常退出,其餘爲異常)固然也能夠用字符串參數,表示錯誤不成功的報錯信息。

import sys

def exitfunc(value):
    print (value)
    sys.exit(0)

print("hello")

try:
    sys.exit(90)
except SystemExit as value:
    exitfunc(value)   

print("come?")

運行結果:

hello
90

程序首先打印hello,在執行exit(90),拋異常把90傳給values,values在傳進函數中執行,打印90程序退出。後面的」come?」由於已經退出因此不會被打印. 而此時若是把exitfunc函數裏面的sys.exit(0)去掉,那麼程序會繼續執行到輸出」come?」。

 四、sys.modules 

sys.modules是一個全局字典,該字典是python啓動後就加載在內存中。每當程序員導入新的模塊,sys.modules將自動記錄該模塊。當第二次再導入該模塊時,python會直接到字典中查找,從而加快了程序運行的速度。它擁有字典所擁有的一切方法.

import sys

print(sys.modules.keys())
print("**************************************************************************")
print(sys.modules.values())
print("**************************************************************************")
print(sys.modules["os"])

運行結果爲:

dict_keys(['sys', 'builtins', '_frozen_importlib', '_imp', '_thread', '_warnings', '_weakref', 'zipimport', '_frozen_importlib_external', '_io', 'marshal', 'nt', 'winreg', 'encodings', 'codecs', '_codecs', 'encodings.aliases', 'encodings.utf_8', '_signal', '__main__', 'encodings.latin_1', 'io', 'abc', '_abc', 'site', 'os', 'stat', '_stat', 'ntpath', 'genericpath', 'os.path', '_collections_abc', '_sitebuiltins'])
**************************************************************************
dict_values([<module 'sys' (built-in)>, <module 'builtins' (built-in)>, <module '_frozen_importlib' (frozen)>, <module '_imp' (built-in)>, <module '_thread' (built-in)>, <module '_warnings' (built-in)>, <module '_weakref' (built-in)>, <module 'zipimport' (built-in)>, <module '_frozen_importlib_external' (frozen)>, <module 'io' (built-in)>, <module 'marshal' (built-in)>, <module 'nt' (built-in)>, <module 'winreg' (built-in)>, <module 'encodings' from 'C:\\Program Files\\Python37\\lib\\encodings\\__init__.py'>, <module 'codecs' from 'C:\\Program Files\\Python37\\lib\\codecs.py'>, <module '_codecs' (built-in)>, <module 'encodings.aliases' from 'C:\\Program Files\\Python37\\lib\\encodings\\aliases.py'>, <module 'encodings.utf_8' from 'C:\\Program Files\\Python37\\lib\\encodings\\utf_8.py'>, <module '_signal' (built-in)>, <module '__main__' from 'C:\\Users\\Se7eN_HOU\\Desktop\\demo.py'>, <module 'encodings.latin_1' from 'C:\\Program Files\\Python37\\lib\\encodings\\latin_1.py'>, <module 'io' from 'C:\\Program Files\\Python37\\lib\\io.py'>, <module 'abc' from 'C:\\Program Files\\Python37\\lib\\abc.py'>, <module '_abc' (built-in)>, <module 'site' from 'C:\\Program Files\\Python37\\lib\\site.py'>, <module 'os' from 'C:\\Program Files\\Python37\\lib\\os.py'>, <module 'stat' from 'C:\\Program Files\\Python37\\lib\\stat.py'>, <module '_stat' (built-in)>, <module 'ntpath' from 'C:\\Program Files\\Python37\\lib\\ntpath.py'>, <module 'genericpath' from 'C:\\Program Files\\Python37\\lib\\genericpath.py'>, <module 'ntpath' from 'C:\\Program Files\\Python37\\lib\\ntpath.py'>, <module '_collections_abc' from 'C:\\Program Files\\Python37\\lib\\_collections_abc.py'>, <module '_sitebuiltins' from 'C:\\Program Files\\Python37\\lib\\_sitebuiltins.py'>])
**************************************************************************
<module 'os' from 'C:\\Program Files\\Python37\\lib\\os.py'>

五、sys.stdin, sys.stdout, sys.stderr 

stdin,stdout,stderr在Python中都是文件屬性對象, 他們在python啓動時自動與shell環境中的標準輸入, 輸出, 出錯相關. 而python程序在shell中的I/O重定向是有shell來提供的,與python自己沒有關係.python程序內部將stdin, stdout, stderr讀寫操做重定向到一個內部對象.

#import sys
print("Hi, %s!' %input('Please enter your name: "))
#運行結果:Please enter your name: er
#Hi, er!

#等同於:
import sys
print('Please enter your name:')
name=sys.stdin.readline()[:-1]
print('Hi, %s!' %name)


#標準輸出
print('Hello World!\n')
#等同於:
import sys
sys.stdout.write('Hello world!\n')
相關文章
相關標籤/搜索