本節大綱:
- 模塊定義、導入、優化詳解
1. 模塊定義、導入、優化詳解
1、定義
模塊,用一砣代碼實現了某個功能的代碼集合,本質就是.py結尾的python文件。
包,用來從邏輯上組織模塊的,本質就是一個目錄(必須帶有一個_init_.py文件)
類似于函數式編程和面向過程編程,函數式編程則完成一個功能,其他代碼用來調用即可,提供了代碼的重用性和代碼間的耦合。而對于一個復雜的功能來,可能需要多個函數才能完成(函數又可以在不同的.py文件中),n個 .py 文件組成的代碼集合就稱為模塊。
如:os 是系統相關的模塊;file是文件操作相關的模塊
模塊分為三種:
自定義模塊
內置標準模塊(又稱標準庫)
開源模塊
自定義模塊 和開源模塊的使用參考 http://www.cnblogs.com/wupeiqi/articles/4963027.html
2、導入方法
import module_name
import module1_name,module2_name
from module_name import *
from module_name import m1,m2,m3 #不推薦,直接復制粘貼
from module_alex import logger as lpgger_alex
3、import的本質
導入模塊的本質就是把Python文件解釋一遍
導入包的本質就是執行該包下的_init_.py文件
4、導入優化
from module_name import m #直接一次導入,如果要多次調用m時可用
5、模塊的分類
a:標準庫
b:開源模塊
c:自定義模塊
標準庫:
1.time與datetime
在Python中,通常有這幾種方式來表示時間:
1)時間戳
2)格式化的時間字符串
3)元組(struct_time) 共九個元素
2.Range模塊
random.random() 生成一個0到1的隨機浮點數:0<=n<1
random.randint(a,b) 生成一個指定范圍內的整數:a<=n<=b
random.randrange(a,b)
random.choice
random.randrange
生成隨機驗證碼:
import random
check_code=''
for i in range(4):
current=random.randint(0,4)
if current == i:
tmp=chr(random.randint(65,90))
else:
tmp=random.randint(0,9)
check_code += str(tmp)
print(check_code)
3.OS模塊
4.sys模塊
sys.argv 命令行參數List,第一個元素是程序本身路徑
sys.exit(n) 退出程序,正常退出時exit(0)
sys.version 獲取python解釋程序的版本信息
sys.maxint 最大Int值
sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值
sys.platform 返回操作系統平臺名稱
sys.stdout.write('please:')
val = sys.stdin.readline()[:-1]
5.shutil模塊 ——python高級的文件、文件夾、壓縮包處理模塊
shutil.copyfileobj(fsrc,fdst[,length])
將文件內容拷貝到另一個文件中,可以部分內容(需要open打開文件,編碼utf-8)
shutil.copyfile(src,dst)
拷貝文件(只需輸入文件名,不用open打開)
shutil.copymode(src,dst)
僅拷貝權限。內容、組、用戶均不變
shutil.copystat(src,dst)
拷貝狀態信息,包括:mode bits,atime,mtime, flags
shutil.copy(src,dst)
拷貝文件和權限
shutil.copy2(src,dst)
拷貝文件和狀態信息
shutil.copytree(src,dst,symlinks=False,ignore=None)
遞歸的去拷貝文件(拷貝目錄)
shutil.rmtree(path,[,ignore_errors[,onerror]])
遞歸的去刪除文件(刪除目錄)
shutil.move(src,dst)
遞歸的去移動文件
shutil.make_archive(base_name,format,...)
創建壓縮包并返回文件路徑,例如:zip、tar
-base_name:包名,路徑
-format:壓縮包種類,"zip","tar"
-root_dir:要壓縮的那文件夾路徑
-owner:用戶
-group:組
-logger:用于記錄日志,通常是logging.Logger對象
shutil對壓縮包的處理是調用zipfile和tarfile兩個模塊來進行的
6.shelve模塊
shelve模塊是一個簡單的k,v將內存數據通過文件持久化的模塊,可持久化任何pickle可支持的Python數據格式
import shelve
d = shelve.open('shelve.test') #打開文件
info = {'age':22,'job':'it'}
name = ['alex','rain','e']
d['info'] = info
d['name'] = name
print (d.get('name'))
print (d.get('info'))
d.close
7.xml模塊
xml的格式如下,就是通過<>節點來區別數據結構的:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
xml協議在各個語言里的都 是支持的,在python中可以用以下模塊操作xml
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.xml")
root = tree.getroot()
print(root.tag)
# 遍歷xml文檔
for child in root:
print(child.tag, child.attrib)
for i in child:
print(i.tag, i.text)
# 只遍歷year 節點
for node in root.iter('year'):
print(node.tag, node.text)
修改和刪除xml文檔內容
import xml.etree.ElementTree as ET
tree = ET.parse("xmltest.xml")
root = tree.getroot()
#修改
for node in root.iter('year'):
new_year = int(node.text) + 1
node.text = str(new_year)
node.set("updated","yes")
tree.write("xmltest.xml")
#刪除node
for country in root.findall('country'):
rank = int(country.find('rank').text)
if rank > 50:
root.remove(country)
tree.write('output.xml')
自己創建xml文檔
import xml.etree.ElementTree as ET
new_xml = ET.Element("namelist")
name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
age = ET.SubElement(name,"age",attrib={"checked":"no"})
sex = ET.SubElement(name,"sex")
sex.text = '33'
name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
age = ET.SubElement(name2,"age")
age.text = '19'
et = ET.ElementTree(new_xml) #生成文檔對象
et.write("test.xml", encoding="utf-8",xml_declaration=True)
ET.dump(new_xml) #打印生成的格式
8.ConfigParser模塊
用于生成和修改常見配置文檔,當前模塊的名稱在 python 3.x 版本中變更為 configparser。
來看一個好多軟件的常見文檔格式如下
[DEFAULT]
ServerAliveInterval = 45
Compression = yes
CompressionLevel = 9
ForwardX11 = yes
[bitbucket.org]
User = hg
[topsecret.server.com]
Port = 50022
ForwardX11 = no
如果想用python生成一個這樣的文檔怎么做呢?
import configparser
config = configparser.ConfigParser()
config["DEFAULT"] = {'ServerAliveInterval': '45',
'Compression': 'yes',
'CompressionLevel': '9'}
config['bitbucket.org'] = {}
config['bitbucket.org']['User'] = 'hg'
config['topsecret.server.com'] = {}
topsecret = config['topsecret.server.com']
topsecret['Host Port'] = '50022' # mutates the parser
topsecret['ForwardX11'] = 'no' # same here
config['DEFAULT']['ForwardX11'] = 'yes'
with open('example.ini', 'w') as configfile:
config.write(configfile)
9.hashlib,hmac模塊
hashlib模塊
用于加密相關的操作,3.x里代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib
# ######## md5 ########
m = hashlib.md5()
m.update(b"Hello")
m.update(b"It's me")
#加密內容是全部消息,即“HelloIt's me”
print(m.digest()) #2進制格式hash
print(len(m.hexdigest())) #16進制格式hash
# ######## sha1 ########
hash = hashlib.sha1()
hash.update('admin')
print(hash.hexdigest())
# ######## sha256 ########
hash = hashlib.sha256()
hash.update('admin')
print(hash.hexdigest())
還不夠吊?python 還有一個 hmac 模塊,它內部對我們創建 key 和 內容 再進行處理然后再加密
散列消息鑒別碼,簡稱HMAC,是一種基于消息鑒別碼MAC(Message Authentication
Code)的鑒別機制。使用HMAC時,消息通訊的雙方,通過驗證消息中加入的鑒別密鑰K來鑒別消息的真偽;一般用于網絡通信中消息加密,前提是雙方先要約定好key,就像接頭暗號一樣,然后消息發送把用key把消息加密,接收方用key +
消息明文再加密,拿加密后的值 跟 發送者的相對比是否相等,這樣就能驗證消息的真實性,及發送者的合法性了。
import hmac
h = hmac.new(b'12345', '寶塔鎮河妖'.encode(encoding="utf-8"))#key,value
print h.hexdigest()
10.re模塊
常用正則表達式符號
'.' 默認匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行
'^' 匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE)
'$' 匹配字符結尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以
'*' 匹配*號前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 結果為['abb', 'ab', 'a']
'+' 匹配前一個字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb']
'?' 匹配前一個字符1次或0次
'{m}' 匹配前一個字符m次
'{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果'abb', 'ab', 'abb']
'|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果'ABC'
'(...)' 分組匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 結果 abcabca456c
'\A' 只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的
'\Z' 匹配字符結尾,同$
'\d' 匹配數字0-9
'\D' 匹配非數字
'\w' 匹配[A-Za-z0-9]
'\W' 匹配非[A-Za-z0-9]
's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 '\t'
'(?P<name>...)' 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city")
結果:{'province': '3714', 'city': '81', 'birthday': '1993'}
最常用的匹配語法
re.match 從頭開始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符當做列表分隔符
re.sub 匹配字符并替換
本節作業
開發一個簡單的python計算器
1.實現加減乘除及拓號優先級解析
2.用戶輸入1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2) )
等類似公式后,必須自己解析里面的(),+,-,*,/符號和公式(不能調用eval等類似功能偷懶實現),運算后得出結果,結果必須與真實的計算器所得出的結果一致