'''
模塊:一系列功能的集合體
常見的四種模塊:
1.使用python編寫的.py文件
2.把一系列模塊組織到一起的文件夾(注:文件夾下有一個__init__.py文件,該文件夾稱之為包)
3.使用C編寫並鏈接到python解釋器的內置模塊
4.已被編譯為共享庫或DLL的C或C++擴展
'''
模塊的搜索路徑
'''
搜索順序:內存 => 內置模塊 => sys.path
1.導入模塊會優先在內存中查找
2.內存中沒有被加載的話,再去查找內置模塊
3.還沒有查找到,就根據sys.path中的路徑順序逐一查找
'''
模塊導入的執行流程
'''
導入模塊的指令:
-- 相對於 函數名() 調用函數體,函數調用會進入函數體,從上至下逐句解釋執行函數體代碼
-- 導入模塊,會進入模塊文件,從上至下逐句解釋執行模塊文件代碼
-- 如果在模塊中又遇到導入其他模塊,會接着進入導入的模塊,從上至下逐句解釋執行文件中代碼,依次類推
'''
循環導入
'''
模塊之間出現了環狀導入,如:m1.py 中導入了m2,m2.py 中又導入了m1
循環導入的問題:
-- 導入模塊是要使用模塊中的變量
-- 正常邏輯都是在文件最上方先完成對模塊的導入,再在下方定義自身模塊變量,以及使用導入的模塊中的變量
-- 由於導入模塊的特殊機制,第一次導入模塊會編譯執行導入的模塊,也就是會進入模塊逐句執行模塊內容,再次導入只是使用內存中的名字
-- 就會出現下面的情況,m2在使用m1中的變量x,但變量x卻並未產生,這就出現了循環導入問題
m1.py文件
import m2
x = 10
print(m2.y)
m2.py文件
import m1
y = 10
print(m2.x)
解決循環導入的問題:延后導入
1、將循環導入對應包要使用的變量提前定義,再導入響應的包
2、將導包的路徑放倒函數體中,保證存放導包邏輯的函數調用在要使用的變量定義之后
重點:
問題:from導包極容易出現循環導入問題
解決:取消from導入方式,采用import導入方式
'''
包
'''
一系列功能模塊的集合體
-- 包就是管理功能相近的一系列模塊的文件夾
-- 該文件夾包含一個特殊文件__init__.py
-- 文件夾名就是包名,產生的包名就是指向__init__.py的全局名稱空間
導包完成的三項事:
1.編譯執行包中的__init__.py文件,會在包中__pycache__創建對應的pyc文件
2.產生__init__.py文件的全局名稱空間,用來存放__init__出現的名字
3.產生包名指向__init__.py文件的全局名稱空間 | 指定變量名指向包中指定名字
'''
包中模塊的使用:import
'''
module文件夾
-- __init__.py
-- m1.py
test.py文件
import module
# 在該文件中使用包
'''
# 1.__init__.py文件中產生的普通名字可以直接使用
'''
__init__.py
x = 10
test.py
print(module.x)
'''
# 2.管理的模塊中出現的名字,要通過 包名.模塊名 間接使用
'''
m1.py
num = 10
__init__.py
import module.m1
test.py
print(module.m1.num)
'''
包的嵌套
# 在包中再定義包
# 連包的導入
import 父包.子包
# 重點:導包的.語法,在所有點左側都必須是包
# 正確案例:
import 父包.子包
import 父包.子包.模塊
# 錯誤案例
import 父包.子包.模塊.名字
包中模塊的使用:from...import
'''
使用規則與import差不多,但是導包的.語法需嚴格執行,就是所有點左側都必須是包
'''
導包的兩種方式
# 絕對導入:通過sys.path方式來實現
# 相對導入:通過包內.語法來實現
絕對導入
# 將對應的文件夾添加至sys.path中,就可以直接導入對應文件夾下的模塊
相對導入
# 相對導入是存在於包內的語法
# .代表當前文件夾
# ..代表上一級文件夾
# 存在.語法的文件,不能作為執行文件
time:時間
'''
時間戳(timestamp):time.time()
延遲線程的運行:time.sleep(secs)
(指定時間戳下的)當前時區時間:time.localtime([secs])
(指定時間戳下的)格林威治時間:time.gmtime([secs])
(指定時間元組下的)格式化時間:time.strftime(fmt[,tupletime])
'''
'''
%y 兩位數的年份表示(00-99)
%Y 四位數的年份表示(000-9999)
%m 月份(01-12)
%d 月內中的一天(0-31)
%H 24小時制小時數(0-23)
%I 12小時制小時數(01-12)
%M 分鍾數(00-59)
%S 秒(00-59)
%a 本地簡化星期名稱
%A 本地完整星期名稱
%b 本地簡化的月份名稱
%B 本地完整的月份名稱
%c 本地相應的日期表示和時間表示
%j 年內的一天(001-366)
%p 本地A.M.或P.M.的等價符
%U 一年中的星期數(00-53)星期天為星期的開始
%w 星期(0-6),星期天為星期的開始
%W 一年中的星期數(00-53)星期一為星期的開始
%x 本地相應的日期表示
%X 本地相應的時間表示
%Z 當前時區的名稱
%% %號本身
'''
calendar:日歷
'''
判斷閏年:calendar.isleap(year)
查看某年某月日歷:calendar.month(year, mouth)
查看某年某月起始星期與當月天數:calendar.monthrange(year, mouth)
查看某年某月某日是星期幾:calendar.weekday(year, month, day)
# 注:0代表星期一
'''
datatime:可以運算的時間
'''
當前時間:datetime.datetime.now()
昨天:datetime.datetime.now() + datetime.timedelta(days=-1)
修改時間:datatime_obj.replace([...])
格式化時間戳:datetime.date.fromtimestamp(timestamp)
'''
sys:系統
'''
命令行參數List,第一個元素是程序本身路徑:sys.argv
退出程序,正常退出時exit(0):sys.exit(n)
獲取Python解釋程序的版本信息:sys.version
最大int值:sys.maxsize | sys.maxint
環境變量:sys.path
操作系統平台名稱:sys.platform
'''
# 可以實現py文件作為腳本文件執行,實現外部往內部傳參
def copy(old_file, new_file):
print('復制%s操作成%s' % (old_file, new_file))
def move(old_file, new_file):
print('移動%s操作成%s' % (old_file, new_file))
method_map = {
'copy': copy,
'move': move
}
if len(sys.argv) > 3:
cmd = sys.argv[1]
old_file = sys.argv[2]
new_file = sys.argv[3]
if cmd in method_map:
method_map[cmd](old_file, new_file)
else:
print('該功能暫未提供')
# 啟動cmd命令行,用python解釋器直接執行python文件,傳入指定的參數
os:操作系統
'''
生成單級目錄:os.mkdir('dirname')
生成多層目錄:os.makedirs('dirname1/.../dirnamen2')
重命名:os.rename("oldname","newname")
工作目錄:os.getcwd()
刪除單層空目錄:os.rmdir('dirname')
移除多層空目錄:os.removedirs('dirname1/.../dirnamen')
列舉目錄下所有資源:os.listdir('dirname')
路徑分隔符:os.sep
行終止符:os.linesep
文件分隔符:os.pathsep
操作系統名:os.name
操作系統環境變量:os.environ
執行shell腳本:os.system()
'''
os.path:系統路徑操作
'''
執行文件的當前路徑:__file__
返回path規范化的絕對路徑:os.path.abspath(path)
將path分割成目錄和文件名二元組返回:os.path.split(path)
上一級目錄:os.path.dirname(path)
最后一級名稱:os.path.basename(path)
指定路徑是否存在:os.path.exists(path)
是否是絕對路徑:os.path.isabs(path)
是否是文件:os.path.isfile(path)
是否是路徑:os.path.isdir(path)
路徑拼接:os.path.join(path1[, path2[, ...]])
最后存取時間:os.path.getatime(path)
最后修改時間:os.path.getmtime(path)
目標大小:os.path.getsize(path)
'''
'''
normcase函數
在Linux和Mac平台上,該函數會原樣返回path,在windows平台上會將路徑中所有字符轉換為小寫,並將所有斜杠轉換為飯斜杠。
>>> os.path.normcase('c:/windows\\system32\\')
'c:\\windows\\system32\\'
normpath函數
規范化路徑,如..和/
>>> os.path.normpath('c://windows\\System32\\../Temp/')
'c:\\windows\\Temp'
>>> a='/Users/jieli/test1/\\\a1/\\\\aa.py/../..'
>>> print(os.path.normpath(a))
/Users/jieli/test1
'''
random:隨機數
'''
(0, 1):random.random()
[1, 10]:random.randint(1, 10)
[1, 10):random.randrange(1, 10)
(1, 10):random.uniform(1, 10)
單例集合隨機選擇1個:random.choice(item)
單例集合隨機選擇n個:random.sample(item, n)
洗牌單列集合:random.shuffle(item)
'''
json:序列化
# json: {} 與 [] 嵌套的數據
# 注:json中的字符串必須全部用""來標識
'''
序列化:對象 => 字符串
序列化成字符串:json.dumps(json_obj)
序列化字符串到文件中:json.dump(json_obj, write_file)
# 注:字符形式操作
反序列化成對象:json.loads(json_str)
從文件讀流中反序列化成對象:json.load(read_file)
'''
pickle:序列化
'''
序列化:對象 => 字符串
序列化成字符串:pickle.dumps(obj)
序列化字符串到文件中:pickle.dump(obj, write_bytes_file)
# 注:字節形式操作
反序列化成對象:pickle.loads(bytes_str)
從文件讀流中反序列化成對象:pickle.load(read_bytes_file)
'''
shutil:可以操作權限的處理文件模塊
# 基於路徑的文件復制:
shutil.copyfile('source_file', 'target_file')
# 基於流的文件復制:
with open('source_file', 'rb') as r, open('target_file', 'wb') as w:
shutil.copyfileobj(r, w)
# 遞歸刪除目標目錄
shutil.rmtree('target_folder')
# 文件移動
shutil.remove('old_file', 'new_file')
# 文件夾壓縮
shutil.make_archive('file_name', 'format', 'archive_path')
# 文件夾解壓
shutil.unpack_archive('unpack_file', 'unpack_name', 'format')
shevle:可以用字典存取數據到文件的序列化模塊
# 將序列化文件操作dump與load進行封裝
s_dic = shelve.open("target_file", writeback=True) # 注:writeback允許序列化的可變類型,可以直接修改值
# 序列化::存
s_dic['key1'] = 'value1'
s_dic['key2'] = 'value2'
# 反序列化:取
print(s_dic['key1'])
# 文件這樣的釋放
s_dic.close()
logging:日志模塊
'''
1) root logging的基本使用:五個級別
2)root logging的基本配置:logging.basicConfig()
3)logging模塊四個核心:Logger | Filter | Handler | Formater
4)logging模塊的配置與使用
-- 配置文件:LOGGING_DIC = {}
-- 加載配置文件:logging.config.dictConfig(LOGGING_DIC) => logging.getLogger('log_name')
'''
re:正則模塊(重點)
'''
1)模塊的基本使用
2)正則的語法
3)分組:() | (?:) | (?P<name>)
4)正則的使用方法
'''
hashlib模塊:加密
import hashlib
# 基本使用
cipher = hashlib.md5('需要加密的數據的二進制形式'.encode('utf-8'))
print(cipher.hexdigest()) # 加密結果碼
# 加鹽
cipher = hashlib.md5()
cipher.update('前鹽'.encode('utf-8'))
cipher.update('需要加密的數據'.encode('utf-8'))
cipher.update('后鹽'.encode('utf-8'))
print(cipher.hexdigest()) # 加密結果碼
# 其他算法
cipher = hashlib.sha3_256(b'')
print(cipher.hexdigest())
cipher = hashlib.sha3_512(b'')
print(cipher.hexdigest())
hmac模塊:加密
# 必須加鹽
cipher = hmac.new('鹽'.encode('utf-8'))
cipher.update('數據'.encode('utf-8'))
print(cipher.hexdigest())
configparser模塊:操作配置文件
# my.ini
[section1]
option1_1 = value1_1
option1_2 = value1_2
[section2]
option2_1 = value2_1
option2_2 = value2_2
import configparser
parser = configparser.ConfigParser()
# 讀
parser.read('my.ini', encoding='utf-8')
# 所有section
print(parser.sections())
# 某section下所有option
print(parser.options('section_name'))
# 某section下某option對應的值
print(parser.get('section_name', 'option_name'))
# 寫
parser.set('section_name', 'option_name', 'value')
parser.write(open('my.ini', 'w'))
subprocess模塊:操作shell命令
import subprocess
order = subprocess.Popen('終端命令', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
suc_res = order.stdout.read().decode('系統默認編碼')
err_res = order.stderr.read().decode('系統默認編碼')
order = subprocess.run('終端命令', shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
suc_res = order.stdout.decode('系統默認編碼')
err_res = order.stderr.decode('系統默認編碼')
xlrd模塊:excel讀
年終報表 教學部 市場部 咨詢部 總計 Jan-19 10 15 5 30 Feb-19 10 15 5 30 Mar-19 10 15 5 30 Apr-19 10 15 5 30 May-19 10 15 5 30 Jun-19 10 15 5 30 Jul-19 10 15 5 30 Aug-19 10 15 5 30 Sep-19 10 15 5 30 Oct-19 10 15 5 30 Nov-19 10 15 5 30 Dec-19 10 15 5 30
import xlrd
# 讀取文件
work_book = xlrd.open_workbook("機密數據.xlsx")
# 獲取所有所有表格名稱
print(work_book.sheet_names())
# 選取一個表
sheet = work_book.sheet_by_index(1)
# 表格名稱
print(sheet.name)
# 行數
print(sheet.nrows)
# 列數
print(sheet.ncols)
# 某行全部
print(sheet.row(6))
# 某列全部
print(sheet.col(6))
# 某行列區間
print(sheet.row_slice(6, start_colx=0, end_colx=4))
# 某列行區間
print(sheet.col_slice(3, start_colx=3, end_colx=6))
# 某行類型 | 值
print(sheet.row_types(6), sheet.row_values(6))
# 單元格
print(sheet.cell(6,0).value) # 取值
print(sheet.cell(6,0).ctype) # 取類型
print(sheet.cell_value(6,0)) # 直接取值
print(sheet.row(6)[0])
# 時間格式轉換
print(xlrd.xldate_as_datetime(sheet.cell(6, 0).value, 0))
xlwt模塊:excel寫
import xlwt
# 創建工作簿
work = xlwt.Workbook()
# 創建一個表
sheet = work.add_sheet("員工信息數據")
# 創建一個字體對象
font = xlwt.Font()
font.name = "Times New Roman" # 字體名稱
font.bold = True # 加粗
font.italic = True # 斜體
font.underline = True # 下划線
# 創建一個樣式對象
style = xlwt.XFStyle()
style.font = font
keys = ['Owen', 'Zero', 'Egon', 'Liuxx', 'Yhh']
# 寫入標題
for k in keys:
sheet.write(0, keys.index(k), k, style)
# 寫入數據
sheet.write(1, 0, 'cool', style)
# 保存至文件
work.save("test.xls")
xml模塊
import xml.etree.ElementTree as ET
# 讀文件
tree = ET.parse("xmltest.xml")
# 根節點
root_ele = tree.getroot()
# 遍歷下一級
for ele in root_ele:
print(ele)
# 全文搜索指定名的子標簽
ele.iter("標簽名")
# 非全文查找滿足條件的第一個子標簽
ele.find("標簽名")
# 非全文查找滿足條件的所有子標簽
ele.findall("標簽名")
# 標簽名
ele.tag
# 標簽內容
ele.text
# 標簽屬性
ele.attrib
# 修改
ele.tag = "新標簽名"
ele.text = "新文本"
ele.set("屬性名", "新屬性值")
# 刪除
sup_ele.remove(sub_ele)
# 添加
my_ele=ET.Element('myEle')
my_ele.text = 'new_ele'
my_ele.attrib = {'name': 'my_ele'}
root.append(my_ele)
# 重新寫入硬盤
tree.write("xmltest.xml")