到此以前,咱們都是在一個py文件裏操做,接下來,咱們學習模塊的內容,能夠從其餘文件引入內容(如函數等)python
一個py文件就是一個模塊,模塊是一些類似功能的集合體mysql
模塊具備如下好處sql
(1)減小重複代碼,提升開發效率oracle
(2)使代碼的組織結構更清晰,有條理性app
模塊按來源分爲三類:函數
(1)內置模塊,也就是python解釋器自帶的模塊,如time, os, sys等學習
(2)擴展模塊(第三方模塊),經過pip安裝的模塊優化
(3)自定義模塊,本身寫的模塊ui
先來寫一個模塊,命名爲game_of_thronespa
print("-----來自game_of_throne模塊-----") name = "stack" def hello1(): print("我是game_of_throne模塊的func1") def hello2(): print("我是game_of_throne模塊的func2")
咱們引入game_of_throne模塊,調用裏面的name和func1和func2
1 import game_of_throne # 導入模塊 2 print(game_of_throne.name) # 調用模塊裏的變量 3 game_of_throne.func1() # 調用模塊裏的函數 4 game_of_throne.func2()
執行一下,看看結果
-----來自game_of_throne模塊----- stack 我是game_of_throne模塊的func1 我是game_of_throne模塊的func2
能夠看到,導入模塊時,模塊裏的代碼會自動執行,事實上,模塊被執行時發生了三件事:
1. 建立了一個以被導入模塊名字命名的名稱空間
2. 自動執行模塊中的代碼(將模塊中的全部內容加載到內存)
3. 執行模塊中的代碼需經過模塊名. 的方式獲取
這裏須要注意的是,自動執行僅會在首次導入時進行,以後會直接從內存裏引用
1 import game_of_throne 2 print(game_of_throne.name) 3 game_of_throne.func1() 4 game_of_throne.func2() 5 import game_of_throne # 重複導入只會從內存中引用 6 game_of_throne.func2()
執行結果
-----來自game_of_throne模塊----- stack 我是game_of_throne模塊的func1 我是game_of_throne模塊的func2 我是game_of_throne模塊的func2
import還能夠導入多個模塊
# 方式一:官方推薦 import time import os import sys # 方式二:不推薦 import time,os,sys
模塊導入的另一種方法是:from 模塊名 import 內容,來看一段代碼
1 name = "robert" 2 from game_of_throne import name, func1, func2 3 print(name) 4 func1() 5 func2()
執行結果
-----來自game_of_throne模塊----- stack 我是game_of_throne模塊的func1 我是game_of_throne模塊的func2
能夠看到,從game_of_throne模塊導入的name把本文件裏面的name給覆蓋了,若是把本文件的name放在後面呢,來看
# name = "robert" from game_of_throne import name, func1, func2 name = "robert" print(name) func1() func2()
執行結果
-----來自game_of_throne模塊----- robert 我是game_of_throne模塊的func1 我是game_of_throne模塊的func2
運用這種方法導入時會與本文件裏的重名的內容相互覆蓋,因此使用時需慎重,from game_of_throne import name, func1, func2這句話實際上作了兩件事:
(1)將模塊game_of_throne 中的代碼加載到內存(執行一遍)
(2)將name,func1,func2引入到當前的名稱空間(能夠用globals()驗證)
from game_of_throne import name, func1, func2 print(globals())
執行結果
-----來自game_of_throne模塊----- {'__name__': '__main__', '__doc__': '\n模塊被執行發生了三件事:\n1. 建立一個以被導入模塊的名字命名的名稱空間\n2. 自動執行模塊中的代碼(將模塊中的全部內容加載到內存)\n3. 要想執行模塊中的代碼必須經過模塊名. 的方式執行獲取\n', '__package__': None, '__loader__': <_frozen_importlib_external.SourceFileLoader object at 0x000001AF6D7985F8>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'D:/模塊.py', '__cached__': None, 'name': 'stack', 'func1': <function func1 at 0x000001AF6D86A950>, 'func2': <function func2 at 0x000001AF6D86A9D8>}
能夠看到當前全局變量中有name,func1,func2,說明指定的變量和函數已經被引入到當前的名稱空間。
兩種導入方式對比:
(1)使用from...import...直接將模塊中的內容導入到當前的名稱空間中,以後調用直接使用名字就能夠
(2)使用from...import...比較方便,可是容易與當前文件中的對象衝突
上面的模塊名是否是寫着很費勁啊,咱們能夠給它取一個短一點的名字,就像咱們的小名同樣,之後就用這個小名來調用
import game_of_throne as got got.func1() got.func2()
執行結果
-----來自game_of_throne模塊----- 我是game_of_throne模塊的func1 我是game_of_throne模塊的func2
模塊更名除了方便引用外,還有另一個做用,就是優化代碼,方便拓展(統一接口),好比咱們有兩個模塊:mysql.py和oracle.py
# mysql.py
def sqlparse(): print('from mysql sqlparse') # oracle.py def sqlparse(): print('from oracle sqlparse')
有一點這樣的代碼:
1 import mysql.py 2 import oracle.py 3 db_type = input(">>>") 4 if db_type == "mysql": 5 mysql.sqlparse() 6 elif db_type == "oracle": 7 oracle.sqlparse()
咱們能夠經過模塊的更名對其進行優化
1 db_type = input(">>>") 2 if db_type == "mysql": 3 import mysql as db 4 elif db_type == "oracle": 5 import oracle as db 6 db.sqlparse()
from...import...也能夠更名
from game_of_throne import func1 as f1
也能夠導入全部
from game_of_throne import *
import * 表示導入全部(除去下劃線開頭的名字),這種方式要慎用,由於導入全部極有可能覆蓋掉本文件中的內容,這種方式通常只在兩種狀況下使用:
(1)對導入的模塊瞭如指掌,裏面的全部代碼都清楚,確認過導入以後不會覆蓋原文件的內容
(2)使用__all__控制 * 的範圍(注意__all__放在要導入的模塊裏,而不是本文件裏)
__all__ = ["name", "func2", "func4"]
from game_of_throne import * func1() func3()
執行結果
Traceback (most recent call last): -----來自game_of_throne模塊----- File "D:/模塊.py", line 161, in <module> func1() NameError: name 'func1' is not defined
報錯,fiunc1未找到,說明func1沒有被導入到當前的名稱空間
game_of_throne做爲腳本直接運行,__name__爲__main__
# game_of_throne print(__name__)
執行結果
__main__
import game_of_throne print(__name__)
執行結果
-----來自game_of_throne模塊-----
__main__
補充:if __name__ == "__main__"一般做爲項目的啓動文件用
內存中找-------->built-in內置模塊-------->sys.path
先從內存中找,若是內存中有,直接引用;沒有的話再在內置模塊中找,找不到最後再在sys.path中找。
import sys print(sys.path
執行結果
['D:\\Day13', 'C:\\Python36\\python36.zip', 'C:\\Python36\\DLLs', 'C:\\Python36\\lib', 'C:\\Python36', 'C:\\Python36\\lib\\site-packages', 'C:\\Program Files\\JetBrains\\PyCharm 2018.3.2\\helpers\\pycharm_matplotlib_backend']
若是要引入的模塊不在當前文件所在的文件夾裏須要手動將其路徑添加到sys.path裏
import game_of_throne ModuleNotFoundError: No module named 'game_of_throne'
手動添加到sys.path裏
sys.path.append("D:/Day12")
執行結果
-----來自game_of_throne模塊-----
總結一下:
1. 模塊是集成了類似功能的文件
2. 使用模塊可以減小重複代碼,提升開發效率;使代碼組織結構更清晰
3. 模塊導入的兩種方式
import 模塊名;
from 模塊名 import 內容
4. 模塊更名:as
5. 文件搜索路徑
內存
內置模塊
sys.path