python之模塊、包的導入過程和開發規範
阿新 • • 發佈:2018-09-08
而是 port code 導入模塊 聲明 for 命名 bubuko 根據
摘要:導入模塊、導入包、編程規範 以My_module為例,My_module的代碼如下: __all__ = [‘name‘,‘read‘] print(‘in mymodule‘) name = ‘帥鍋‘ def read(): print(‘in read‘,name) def read2(): print(‘in read2‘,name) if __name__ == ‘__main__‘: print(‘in mymodule‘) print(‘__name__ : ‘,__name__) 一、導入模塊1、import 模塊名 1-1、在import的過程中發生了哪些事情: import一個模塊相當於先執行了一次這個被導入模塊,然後在本命名空間建立一個與被導入模塊命名空間的聯系, 相當於在本命名空間新建了一個變量,這個變量名稱是被導入模塊的名稱,指向被導入模塊的命名空間。 1-2、一個模塊不會被重復導入,也就是說,import了一次這個模塊,然後再import一次,也只是執行了第一次的imoptr import My_module # 執行了 import My_module # 不會執行 1-3、如何去使用被導入模塊中的名字 import My_moduleprint(My_module.name) # 打印出My_module中的name My_module.My_module_fun() # 執行了My_module中的函數 1-4、小結導入模塊的過程 導入模塊的時候: 1.尋找模塊 2.如果找到了,就開辟一塊空間,執行這個模塊 3.把這個模塊中用到的名字都收錄到新開辟的空間中 4.創建一個變量來引用這個模塊的空間(變量名與這個模塊名一致) *1.模塊不會被重復導入 *2.模塊和文件之間的內存空間始終是隔離的 *3.模塊的名字必須是符合變量命名規範的1-5、本文件中存在與導入模塊相同的變量 # My_module中的內容: name = ‘帥鍋‘ def read(): print(‘in read‘,name) # 執行文件的內容: import My_module My_module.read() # in read 帥鍋 name = ‘SB‘ My_module.read() # in read 帥鍋 My_module.name = ‘SB‘ My_module.read() # in read SB 總結: 在本文件中定義了一個與導入模塊相同的變量, 並不會影響導入模塊中的變量,因為這兩個變量是存在不同的命名空間中的,互不影響。 1-6、本文件中存在一個變量,這個變量名是導入的模塊名 這個時候就相當於把指向導入模塊的指針斷開了,再指向新的值 My_module = 1 print(My_module) # 1 My_module.read() #報錯
1-7、一次導入多個模塊的方式 import os,time,My_module 但是一般不建議這麽使用,因為根據pep8規範(python編寫規範): 我們導入模塊的順序應該是:內置模塊,第三方模塊,自定義模塊 import os # 內置 import time # 內置 import django # 第三方 import my_module # 自定義 1-8、給模塊起別名,一旦給模塊起了別名,那麽原名就不能使用了 import My_module as m print(m.name) # 帥鍋 print(My_module.name) # 報錯 1-9、如何判斷模塊能否被導入 sys.path是一個存放了所有模塊路徑的列表, 一個模塊是否能被導入,就看這個模塊所在的目錄在不在sys.path中, 如果這個模塊的路徑不在sys.path中,那麽就不可被導入, 不過可以自己手動添加:sys.path.append(“自定義的模塊路徑”) 1-10、循環引用模塊(看圖)
1-11、運行一個py文件的兩種方式方式 1,直接運行它 : 在cmd終端運行: python xx.py 或者在pycharm中直接運行 當用這種方式運行這個py文件,那麽這個py文件就稱為:腳本 這個時候py文件中的:__name__ == ‘__main__‘ 2,導入它 : 導入一個模塊,也會運行一次這個py文件 當用這種方式運行py文件,這個py文件就稱為:模塊 這個時候py文件中的:__name__ == ‘模塊名‘ import My_module __name__ = ‘my_module ‘ 例如: 在My_module中有這樣的代碼: print(‘in mymodule‘) print(‘__name__ : ‘,__name__) 那麽直接在My_module中運行結果為:in mymodule __name__ : __main__ 在導入My_module的文件中執行導入模塊(會默認執行一次My_module) import My_module 然後執行,結果為:in mymodule __name__ : My_module 2、from xx import xx 2-1在from import的過程中發生了哪些事情 from My_module import name from My_module import read 1,要找到My_module 2,開空間,執行my_module 3,所有的My_module中的名字都存儲在My_module所屬的空間中 4,本文件空間中建立對應的變量名(name,read),分別取引用My_module空間中對應的名字 from My_module import name from My_module import read print(name) # 帥鍋 read() # in read 帥鍋
2-2、引用模塊的變量後,進行修改(看圖) from My_module import name from My_module import read print(name) # 帥鍋 name = ‘aaa‘ read() # in read 帥鍋 print(name) # aaa
2-3、from import 多個內容 from My_module import name,read,read2 2-4、給導入的內容起別名 from My_module import name as n,read as r,read2 as r2 2-5、from import *和 __all__關系 1,只有from import * 沒有__all__的時候,My_module的所有變量都可以在本文件中使用 from My_module import * print(name) # 帥鍋 read() # in read 帥鍋 read2() # in read2 帥鍋 2,即有from import * 也有__all__的時候,只有被__all__聲明的變量才能在本文件中使用 My_module中:__all__ = [‘name‘,‘read‘] 本文件中執行: from My_module import * print(name) # 帥鍋 read() # in read 帥鍋 read2() # 報錯:name ‘read2‘ is not defined 2-6、模塊的導入和修改 模塊在導入後,在程序運行期間,你再去修改導入的模塊,導入的內容依舊是不變的。 如果硬是要在程序運行期間修改模塊的內容,並讓修改的內容生效,那麽可以使用reload. from importlib import reload ‘‘‘ 在這期間修改模塊的內容 ‘‘‘ # 重新reload,修改的內容就生效了 reload(My_module) 3、補充的內容 1.pyc文件、pyi文件 * pyc文件是導入包的時候自動產生的字節碼文件,只能提高程序的啟動效率並不能提高程序的執行效率 2.模塊的導入和修改 * 3.模塊的循環引用 **** 不能循環 4.dir(模塊名) *** 可以獲取這個模塊中的所有名字 二、導入包 1、 1.無論是import形式還是from...import形式,凡是在導入語句中遇到帶點的都是關於包的導入語法。 2. 包是目錄級的(文件夾級),文件夾是用來組成py文件(包的本質就是一個包含__init__.py文件的目錄) 3. import導入文件時,產生名稱空間中的名字來源於文件,import 包,產生的名稱空間的名字同樣來源於文件,即包下的__init__.py,導入包本質就是在導入該文件 4.導入包就相當於執行力這個包下的__init__.py文件,在__init__下導入了什麽模塊,你就等於導入了什麽模塊 強調: 1. 在python3中,即使包下沒有__init__.py文件,import 包仍然不會報錯,而在python2中,包下一定要有該文件,否則import 包會報錯 2. 創建包的目的不是為了運行,而是被導入使用,記住,包只是模塊的一種形式而已,包即模塊 2、目錄結構創建 創建代碼目錄: import os os.makedirs(‘glance/api‘) os.makedirs(‘glance/cmd‘) os.makedirs(‘glance/db‘) l = [] l.append(open(‘glance/__init__.py‘,‘w‘)) l.append(open(‘glance/api/__init__.py‘,‘w‘)) l.append(open(‘glance/api/policy.py‘,‘w‘)) l.append(open(‘glance/api/versions.py‘,‘w‘)) l.append(open(‘glance/cmd/__init__.py‘,‘w‘)) l.append(open(‘glance/cmd/manage.py‘,‘w‘)) l.append(open(‘glance/db/models.py‘,‘w‘)) map(lambda f:f.close() ,l) 目錄結構: glance/ #Top-level package ├── __init__.py #Initialize the glance package ├── api #Subpackage for api │ ├── __init__.py │ ├── policy.py │ └── versions.py ├── cmd #Subpackage for cmd │ ├── __init__.py │ └── manage.py └── db #Subpackage for db ├── __init__.py └── models.py 文件內容 #policy.py def get(): print(‘from policy.py‘) #versions.py def create_resource(conf): print(‘from version.py: ‘,conf) #manage.py def main(): print(‘from manage.py‘) #models.py def register_models(engine): print(‘from models.py: ‘,engine) 3、註意事項 1.關於包相關的導入語句也分為import和from ... import ...兩種,但是無論哪種,無論在什麽位置,在導入時都必須遵循一個原則: 凡是在導入時帶點的,點的左邊都必須是一個包,右邊可以是包也可以是文件,否則非法。可以帶有一連串的點,如glance.db.models,但都必須遵循這個原則。 2.對於導入後,在使用時就沒有這種限制了,點的左邊可以是包,模塊,函數,類(它們都可以用點的方式調用自己的屬性)。 4、import:import什麽,調用的時候就要寫全 import glance.db.models glance.db.models.register_models(‘hello‘) # from models.py: hello 5、from...import 需要註意的是from後import導入的模塊,必須是明確的一個不能帶點,否則會有語法錯誤,如:from a import b.c是錯誤語法 from glance.db import models models.register_models(‘hello‘) from glance.db.models import register_models register_models(‘hello‘) 6、__init__.py文件 不管是哪種方式,只要是第一次導入包或者是包的任何其他部分,都會依次執行包下的__init__.py文件, 也就是說每次導入一個包都會先執行包下的__init__.py文件。 在包api下的__init__.py文件寫入這樣的代碼: print(‘__init__‘) __all__ = [‘policy‘] 然後在主程序執行: from glance.api import * policy.get() # __init__ # from policy.py versions.create_resource(‘aa‘) # 報錯:name ‘versions‘ is not defined 7、絕對導入和相對導入 我們的最頂級包glance是寫給別人用的,然後在glance包內部也會有彼此之間互相導入的需求,這時候就有絕對導入和相對導入兩種方式: 絕對導入:以glance作為起始 相對導入:用.或者..的方式最為起始(只能在一個包中使用,不能用於不同目錄內) 一旦使用了相對導入,那麽這個文件只能作為模塊使用,不用直接執行了。 8、單獨導入包 直接單獨導入包,比如import glance,是不會導入包中的模塊的, 直接導入包名稱的時候,只會去執行包中的__init__文件,所以單獨導入包名稱的時候,需要 去包下的__init__文件中導入相應的模塊。 例如:在與glance同級的test.py文件下運行代碼: import glance glance.api.policy.get() # 報錯:module ‘glance‘ has no attribute ‘api‘ 導入包就等於導入包下__init__的內容,而此時在glance的__init__內沒有導入相應的內容,所以會報錯 在glance包下的__init__寫入: from glance.api import policy 再次執行 import glance glance.api.policy.get() 結果:from policy.py 三、開發規範(插圖)
python之模塊、包的導入過程和開發規範