您好!此筆記的文本和代碼以網盤形式分享於文末!
因個人能力有限,錯誤處歡迎大家交流和指正!基礎部分內容簡單,但多且零散!
python之路——模塊和包 | ||
模塊定義:模塊是一個包含所有你定義的函數和變量的文件,其後綴名是.py | ||
import加載的模塊分爲四個通用類別: 1 使用python編寫的代碼(.py文件) 2 已被編譯爲共享庫或DLL的C或C++擴展 3 包好一組模塊的包 4 使用C編寫並鏈接到python解釋器的內置模塊 |
||
模塊可以包含可執行的語句和函數的定義,這些語句的目的是初始化模塊,它們只在模塊名第一次遇到導入import語句時才執行 | ||
每個模塊都是一個獨立的名稱空間,定義在這個模塊中的函數,把這個模塊的名稱空間當做全局名稱空間,不用擔心我們定義在自己模塊中全局變量會在被導入時,與使用者的全局變量衝突 | ||
爲源文件(my_module模塊)創建新的名稱空間,在my_module中定義的函數和方法若是使用到了global時訪問的就是這個名稱空間。 | ||
.在新創建的命名空間中執行模塊中包含的代碼,見初始導入import my_module | ||
用法 | 栗子 | 結果 |
mymodule代碼 | print('from the my_module.py') money = 1000 def read1(): print('my_module->read1->money',money) def read2(): print('my_module->read2 calling read1') read1() def change(): global money money = 0 |
|
模塊的獨立名稱空間 | # 模塊測試 import mymodule # 變量、函數的獨立名稱空間 money = 10 print(money) print(mymodule.money) print(money) mymodule.change() print(money) print(mymodule.money) # 函數名相同測試 def read1(): print('======') mymodule.read1() read1() |
from the my_module.py 10 1000 10 10 0 my_module->read1->money 0 ====== |
模塊的別名 | # 模塊別名 import mymodule as mym print(mym.money) |
from the my_module.py 1000 |
據用戶輸入選擇模塊 | # 根據輸入選擇不同的模塊 db_type = input('mysql or oracle: ') if db_type == 'mysql': import mysqltest as db elif db_type == 'oracle': import oracletest as db db.sqlparse() |
mysql or oracle: mysql from mysql sqlparse |
選擇讀取不同的模塊 | # if file_format == 'xml': # import xmlreader as reader # elif file_format == 'csv': # import csvreader as reader # data = reader.read_date(filename) |
|
一行中導入多個模塊 | # 一行中導入多個模塊 # import sys,os,re |
|
from導入 仍然是使用模塊的 命名空間 |
# from 導入 from mymodule import read1 money = 15 read1() |
from the my_module.py my_module->read1->money 1000 |
from導入 函數調用 仍然是使用模塊中的函數 |
from mymodule import read2 def read1(): print('********') read2() |
from the my_module.py my_module->read2 calling read1 my_module->read1->money 1000 |
覆蓋關係 | from mymodule import read1 def read1(): print('********') read1() |
from the my_module.py ******** |
變量賦值的綁定關係 | from mymodule import money, read1 money = 100 # 將當前位置的名字money綁定到了100 print(money) # 打印當前的名字 read1() # 讀取my_module.py中的名字money,仍然爲1000 |
from the my_module.py 100 my_module->read1->money 1000 |
from導入的重命名 和導入多個 |
# 支持as from mymodule import read1 as read # 支持導入多行 from mymodule import (read1, read2, money) |
|
from my_module import * | 把my_module中所有的不是以下劃線(_)開頭的名字都導入到當前位置 | 缺點:造成誤覆蓋和可讀性差 |
from my_module import * 優化 | __all__=['money','read1'] #這樣在另外一個文件中用from my_module import *就這能導入列表中規定的兩個名字 | |
模塊的循環引用 | ||
模塊的加載與修改 | def func1(): print('func1') import time,importlib import aa time.sleep(20) # 等待期間修改aa.py中的內容 # importlib.reload(aa) aa.func1() |
|
將模塊作爲腳本執行 | 當做腳本運行: __name__ 等於'__main__' 當做模塊導入: __name__= 模塊名 def fib(n): a, b = 0, 1 while b < n: print(b, end=' ') a, b = b, a+b print() if __name__ == "__main__": print(__name__) num = input('num :') fib(int(num)) |
|
模塊搜索路徑 | ||
查找模塊中定義的名字 | import my_module dir(my_module) |
3.4 模塊的搜索路徑 |
編譯python文件:爲了提高加載模塊的速度,解釋器會在__pycache__目錄中下緩存每個模塊編譯後的版本.pyc文件 | ||
你可以使用-O或者-OO轉換python命令來減少編譯模塊的大小 | ||
- O 轉換會幫你去掉assert語句 | ||
-OO轉換會幫你去掉assert語句和__doc__文檔字符串 |
||
在速度上從.pyc文件中讀指令來執行不會比從.py文件中讀指令執行更快,只有在模塊被加載時,.pyc文件纔是更快的 | ||
dir()不會列舉出內建函數或者變量的名字 | import builtins dir(builtins) |
|
包 | ||
包是一種通過使用‘.模塊名’來組織python模塊名稱空間的方式。 | ||
凡是在導入語句中(而不是在使用時)遇到帶點的,都要第一時間提高警覺:這是關於包纔有的導入語法 | ||
包是目錄級的(文件夾級),文件夾是用來組成py文件(包的本質就是一個包含__init__.py文件的目錄) | ||
產生名稱空間中的名字來源於文件,import 包,產生的名稱空間的名字同樣來源於文件,即包下的__init__.py,導入包本質就是在導入該文件 | ||
在python3中,即使包下沒有__init__.py文件,import 包仍然不會報錯 | ||
創建包的目的不是爲了運行,而是被導入使用,記住,包只是模塊的一種形式而已,包即模塊 | ||
模塊 最重要是 自定義模塊 | ||
包的絕對路徑和相對路徑 | ||
包的引用和 特點 | ||
用法 | 栗子 | 結果 |
創建一個包 | # 創建包 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/__init__.py', 'w')) l.append(open('glance/db/models.py', 'w')) map(lambda f: f.close(), l) |
|
import 用法 | # 當前文件與glance同級別的中測試 import glance.db.models glance.db.models.register_models('mysql') |
from models.py: mysql |
form import 用法 | # import導入的模塊明確且不能帶點 from glance.db import models models.register_models('mysql') from glance.db.models import register_models register_models('mysql') |
from models.py: mysql from models.py: mysql |
__init__.py文件 | # __init__.py文件 第一次導入包或者是包的任何其他部分, # 都會依次執行包下的__init__.py文件 # 修改glance下 init文件 查看執行 from glance.db import models models.register_models('mysql') |
form glance __init__.py File from models.py: mysql |
from glance.api import * 的用法 | # 該語句只會導入包api下__init__.py文件中定義的名字, # 可以在這個文件中定義__all___ """ #在api文件夾下__init__.py中定義 x=10 def func(): print('from api.__init.py') __all__=['x','func','policy'] """ # 使用import * 的用法 但是versions 依然是不能使用的 from glance.api import * policy.get() |
form glance __init__.py File from policy.py |
絕對導入和相對導入 | # 絕對導入和相對導入 """ 包內文件互掉, 注意事項和優缺點 絕對導入:以glance作爲起始 相對導入:用.或者..的方式最爲起始 (只能在一個包中使用,不能用於不同目錄內) """ # 在glance/api/version.py 文件中 # # 絕對導入 # from glance.cmd import manage # manage.main() # # # 相對導入 # from ..db import models # models.register_models('db') # 測試結果 與glance同級文件 from glance.api import versions # # 導入自定義的子模塊時,應該使用form……import # # 絕對或者相對導入,且包的相對導入只能用from的形式。 |
form glance __init__.py File from manage.py from models.py: db |
絕對路徑問題 | 看視頻 欠 | |
相對路徑問題 | 看視頻 欠 | |
單獨導入包 | # 單獨導入包 # 單獨導入包名稱時不會導入包中所有包含的所有子模塊 import glance glance.cmd.manage.main() |
form glance __init__.py File Traceback (most recent call last): |
# 解決辦法 """ #在glance/__init__.py中添加 from . import cmd #在glance/cmd/__init__.py中添加 from . import manage """ import glance glance.cmd.manage.main() |
form glance __init__.py File from manage.py |
|
python軟件開發 目錄結構規範 |
# python軟件開發目錄結構規範 import os # bin/ 存放項目的一些可執行文件 os.makedirs('soft/bin') # conf/ 配置文件 os.makedirs('soft/conf') # core/ 存放項目的所有源代碼(核心代碼) # 1>源代碼中的所有模塊、包都應該放在此目錄。不要置於頂層目錄。 os.makedirs('soft/core') # core/tests/ 子目錄 存放單元測試代碼; os.makedirs('soft/core/tests') # db/ 數據庫文件 os.makedirs('soft/db') # lib/ 庫文件,放自定義模塊和包 os.makedirs('soft/lib') # log/ 日誌文件 os.makedirs('soft/log') # docs/ 存放一些文檔 os.makedirs('soft/doc') l = [] # README 是項目說明文件 l.append(open('soft/README', 'w')) l.append(open('soft/__init__.py', 'w')) |
|
# start 寫啓動程序 l.append(open('soft/bin/start.py', 'w')) l.append(open('soft/bin/__init__.py', 'w')) # setting 寫相關配置 l.append(open('soft/conf/setting.py', 'w')) l.append(open('soft/conf/__init__.py', 'w')) # my_log_setting 存放logging配置文件 l.append(open('soft/conf/my_log_setting.py', 'w')) # config.ini 存放配置文件 l.append(open('soft/conf/config.ini', 'w')) # main 程序的入口,存放核心邏輯代碼 l.append(open('soft/core/main.py', 'w')) l.append(open('soft/core/__init__.py', 'w')) # 存放單元測試代碼 l.append(open('soft/core/tests/test.main.py', 'w')) l.append(open('soft/core/tests/__init__.py', 'w')) # 寫數據庫文件 l.append(open('soft/db/db.json', 'w')) # 存放常用功能 l.append(open('soft/lib/common.py', 'w')) l.append(open('soft/lib/__init__.py', 'w')) # 存放日誌 l.append(open('soft/log/all.log', 'w')) map(lambda f: f.close(), l) |
願有更多的朋友,在網頁筆記結構上分享更邏輯和易讀的形式:
鏈接:暫無
提取碼:暫無