Python 經常使用模塊

##Python之路 Day5 經常使用模塊node

####import 導入模塊python


1.定義git

相似於函數式編程和麪向過程編程,函數式編程則完成一個功能,其餘代碼用來調用便可,提供了代碼的重用性和代碼間的耦合。而對於一個複雜的功能來,可能須要多個函數才能完成(函數又能夠在不一樣的.py文件中),多個.py 文件組成的代碼集合就稱爲模塊,是爲了實現某個功能的代碼集合。

2.導入模塊正則表達式

導入模塊其實就是告訴Python解釋器去解釋那個py文件,導入一個py文件,解釋器解釋該py文件。導入一個包,解釋器解釋該包下的 __init__.py 文件。
   
導入方法:   
import module
from module.xx.xx import xx
from module.xx.xx import xx as rename  
from module.xx.xx import *

3.模塊的分類算法

  • 標準庫
  • 開源模塊
  • 自定義模塊

####時間模塊

模塊有time,datetime表示方式有(1)時間戳,(2)格式化時間字符串,(3)元組(struct_time)共九個元素。shell

時間戳express

>>> time.time()
1550499641.1268253    #打印從19700101 8:00:00到當前時間所經歷的秒數
>>> time.mktime(time.strptime("2018-11-08 15:32:02","%Y-%m-%d %X"))
1541662322.0          #將當前時間轉爲時間戳

格式化時間字符串編程

>>> time.ctime(time.time())
'Mon Feb 18 22:24:59 2019'               #接收的參數是字符串
>>> time.asctime(time.localtime())
'Mon Feb 18 22:25:02 2019'               #接收的參數是元組
>>> print(datetime.datetime.now())
2019-02-18 22:26:41.758610
>>> time.strftime('%X %Y-%m-%d',time.localtime()) 
'22:33:20 2019-02-18'                    #根據time.localtime()來自定義時間
>>> print(time.strptime("2018-11-08 15:32:02","%Y-%m-%d %X"))
time.struct_time(tm_year=2018, tm_mon=11, tm_mday=8, tm_hour=15, tm_min=32, tm_sec=2, tm_wday=3, tm_yday=312, tm_isdst=-1)     #將'2018-11-08 15:32:02'轉爲time.localtime()格式,#先後格式須要一一對應可是順序不須要。

元組(struct_time)bash

>>> time.gmtime()       #UTC標準時間
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=18, tm_hour=14, tm_min=30, tm_sec=32, tm_wday=0, tm_yday=49, tm_isdst=0)
>>> time.localtime()    #當前時間
time.struct_time(tm_year=2019, tm_mon=2, tm_mday=18, tm_hour=22, tm_min=30, tm_sec=36, tm_wday=0, tm_yday=49, tm_isdst=0)

獲取過去或將來時間dom

>>> print(datetime.datetime.now() + datetime.timedelta(3))
2019-02-21 22:37:31.583559      #三天後時間
>>> print(datetime.datetime.now() + datetime.timedelta(hours=3))
2019-02-19 01:38:06.303301      #三小時後時間
>>> print(datetime.datetime.now() + datetime.timedelta(hours=-3))
2019-02-18 19:38:28.503632      #三小時前時間

替換時間

>>> print(datetime.datetime.now().replace(minute=3,hour=2))
2019-02-18 02:03:08.503691

####random模塊

import random
print(random.random())          ##生成0到一之間隨機數
print(random.randint(100,999))  ##生成100到999之間隨機數
print random.randrange(1,10)    ##生成1到10之間隨機數,不包含10
print(random.choice([1,'23',[4,5]]))  #從列表中返回其中一個值 
print(random.uniform(1,3))      ##大於1小於3的小數,如1.927109612082716
print(random.sample('hello',3)) ##從整體序列或集合中選擇多個惟一的隨機元素,以列表形式返回。		

item=[1,3,5,7,9]
random.shuffle(item)            ##打亂item的順序,至關於"洗牌"
print(item)

import string
print(string.ascii_lowercase)       ##生成小寫字母
print(string.ascii_uppercase)       ##生成大寫字母
print(string.ascii_letters)         ##生成全部字母
print(string.digits)                ##生成0-9數字

生成隨機驗證碼:
import random,string
checkcode = ''
road=True
for i in range(8):
    if road:
        checkcode+=random.choice(string.ascii_letters)
        road=False
    else:
        checkcode += random.choice(string.digits)
        road=True
print(checkcode)

####os模塊

提供對操做系統進行調用的接口

import os
os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑
os.chdir("dirname")  改變當前腳本工做目錄;至關於shell下cd
os.curdir  返回當前目錄: ('.')
os.pardir  獲取當前目錄的父目錄字符串名:('..')
os.makedirs('dirname1/dirname2')    可生成多層遞歸目錄
os.removedirs('dirname1')    若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推
os.mkdir('dirname')    生成單級目錄;至關於shell中mkdir dirname
os.rmdir('dirname')    刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname
os.listdir('dirname')    列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印
os.remove()  刪除一個文件
os.rename("oldname","newname")  重命名文件/目錄
os.stat('path/filename')  獲取文件/目錄信息
os.sep    輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/"
os.linesep    輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n"
os.pathsep    輸出用於分割文件路徑的字符串
os.name    輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix'
os.system("bash command")  運行shell命令,直接顯示,結果沒法賦值給變量
os.popen("bash command")   執行系統命令,能夠賦值保存可是須要read讀。
os.environ  獲取系統環境變量
os.path.abspath(path)  返回path規範化的絕對路徑
os.path.split(path)  將path分割成目錄和文件名二元組返回
os.path.dirname(path)  返回path的目錄。其實就是os.path.split(path)的第一個元素
os.path.basename(path)  返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素
os.path.exists(path)  若是path存在,返回True;若是path不存在,返回False
os.path.isabs(path)  若是path是絕對路徑,返回True
os.path.isfile(path)  若是path是一個存在的文件,返回True。不然返回False
os.path.isdir(path)  若是path是一個存在的目錄,則返回True。不然返回False
os.path.join(path1[, path2[, ...]])  將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略
os.path.getatime(path)  返回path所指向的文件或者目錄的最後存取時間
os.path.getmtime(path)  返回path所指向的文件或者目錄的最後修改時間

####shutil模塊

import shutil
shutil.copyfile('1.txt','2.txt')      拷貝文件
shutil.copy('1.txt','2.txt')          拷貝文件和權限     
shutil.copy2('1.txt','2.txt')         拷貝文件和權限,還有時間等屬性。
shutil.copymode('f1.log', 'f2.log')   僅拷貝權限。內容、組、用戶均不變,目標文件須要已經存在。
shutil.copystat('f1.log', 'f2.log')   僅拷貝權限和狀態信息訪問時間等。內容、組、用戶均不變,目標文件須要已經存在。
shutil.move('1.txt','2.txt')          移動文件,相同目錄下至關與更名
shutil.copytree(src, dst)             拷貝目錄
shutil.rmtree(path)                   刪除目錄

壓縮目錄:
shutil.make_archive(base_name, format,...)
base_name: 壓縮包的文件名,也能夠是壓縮包的路徑。只是文件名時,則保存至當前目錄,不然保存至指定路徑。
format:	   壓縮包種類,「zip」, 「tar」, 「bztar」,「gztar」
root_dir:  要壓縮的文件夾路徑(默認當前目錄)壓縮文件。
注:默認會給你的壓縮包加上後綴名。

shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細:
import zipfile

#壓縮
z=zipfile.ZipFile('test.zip','w')
z.write('test.xml')
z.write('test1.xml')
z.close()

#解壓出一個文件
z=zipfile.ZipFile('test.zip','r')
z.extract(member='test.xml')
z.close()

#解壓出全部文件
z=zipfile.ZipFile('test.zip','r')
z.extractall(member='test.xml')
z.close()

import tarfile

#壓縮
tar = tarfile.open('your.tar','w')
tar.add('test.xml', arcname='test.xml')
tar.add('test1.xml', arcname='test1.xml')
tar.close()

# 解壓
tar = tarfile.open('your.tar','r')
tar.extractall()  # 可設置解壓地址
tar.close()

####shelve模塊 shelve模塊以k,v格式存儲數據,能夠持久化任何pickle可支持的Python數據類型。

#寫入:
d=shelve.open('shelve_test')
info={'age':22,'j  ob':'it'}
name=['zyl','syf','test']
d['in']=info
d['na']=name
d.close()

#讀取例
d=shelve.open('shelve_test')
print(d.get('in '))
結果:{'age': 22, 'j  ob': 'it'}

####xml模塊

import xml.etree.ElementTree as ET

#讀取:
tree = ET.parse('xmltest.xml')
root=tree.getroot()                       
for i in root:
    print(i.tag,i.attrib)        ##tag是第一層的標籤名,attrib是第一層標籤名的信息。
    for c in i:                        
         print(c.tag,c.text,c.attrib)    ##打印第二層的標籤名,文本數據,標籤名的信息。

for node in root.iter('year'):
    print(node.tag,node.text)            ##只打印單個節點信息,就算year在多級目錄下也會打印。

#修改:
tree = ET.parse('xmltest.xml')
root=tree.getroot()
for node in root.iter('year'):
    node.text=str(int(node.text)+1)          ##全部標籤爲year的內容加1
    node.set("updated",'yes')                ##設置標籤屬性。

tree.write('xmltest.xml')                    ##修改完畢後須要在寫入到文件

刪除某一段:
tree = ET.parse('xmltest.xml')
root=tree.getroot()
for country in root.findall('country'):
    rank=int(country.find('year').text)
    if rank == 2012:
         root.remove(country)                #刪除年份爲2012的節點
tree.write('output.xml')

編寫xml文件:
new_xml=ET.Element('data')                                               #一級標籤
info=ET.SubElement(new_xml,"personinfo",attrib={'enrolled':'yes'})       #二級標籤
info2=ET.SubElement(new_xml,"personinfo2",attrib={'a':'666'})            #二級標籤

name=ET.SubElement(info,"name")                                          #三級標籤
age=ET.SubElement(info,'age')
name.text='zyl'                                                          #給三級標籤設置值
age.text='30'               

name=ET.SubElement(info2,"name")                                         #三級標籤
age=ET.SubElement(info2,'age')
name.text='wq'
age.text='16'


et=ET.ElementTree(new_xml)                                               #生成et對象
et.write('new_xml',encoding="utf-8",xml_declaration=True)                #寫入到new_xml文件中

####configparser模塊 用於生成和修改常見配置文檔 生成以下格式:

[Default]
a = 1
b = 2
c = 3
forwardx11 = yes

[bit]
user = hg

[topse]
port = 5022
forwardx11 = no

若是想用python生成一個這樣的文檔怎麼作呢?

import configparser

#編寫文件:
config=configparser.ConfigParser()
config["Default"]={'a':1,
            'b':2,
            'c':3}
config['bit']={}
config['bit']['user']='hg'

config['topse']={}
a=config['topse']
a['port']='5022'
a['forwardx11']='no'

config['Default']['ForwardX11']='yes'

with open('ConfParser.py','w') as configfile:
    config.write(configfile)

#返回節名稱列表,不包括[DEFAULT]:
import configparser
config = configparser.ConfigParser()
config.read('example.ini')
config.sections()

#讀取模塊下單獨的選項:
import configparser
config = configparser.ConfigParser()
config.read('example.ini')
config['bitbucket.org']['User']

#讀取模塊下選項和對應的參數:
>>>print(config.items('bit'))
[('user', 'hg')]

#只讀取模塊下全部的選項:
>>>config.options('bit')
['user']

#刪除單個模塊:
config.remove_section('group1')

#添加一個模塊:
config.add_section('wupeiqi')

#給新加的模塊添加一個鍵值對
config.set('wupeiqi','user','zyl')

#修改一個選項的值:
config.set('group2','k1',11111)     

#刪除一個選項:
config.remove_option('group2','age')

#注意:全部修改文件的操做都須要衝新寫入到一個文件中。
config.write(open('ConfParser.py','w'))

####hashlib模塊 用於加密相關的操做,3.x裏代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512,MD5算法

import hashlib

#md5:
 m = hashlib.md5()
 m.update(b"Hello")         ##必須爲bytes格式
 m.update(b"It's me")       ##多個值會組成一個值,至關於b「Hello It's me」
 print(m.digest())          #2進制格式hash
 print(m.hexdigest())       #16進制格式hash
 
#sha256:
 m = hashlib.sha512()
 m.update(b"Hello")
 print(m.hexdigest())
 
#加密中文格式:
 m = hashlib.sha512()
 m.update("小朱朱".encode(encoding='utf-8'))
 print(m.hexdigest())

####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-zA-Z0-9]
'[^]'   排除其中全部字符


'\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'

#flags標誌位
re.I(re.IGNORECASE): 忽略大小寫(括號內是完整寫法,下同)
例:re.search("([a-z]+)","aaaAaAC234aaa",flags=re.I)
S(DOTALL): 點任意匹配模式,改變'.'的行爲,能夠匹配到換行符。   
例:re.search(".+","aaaAaAC\r\n234aaa",flags=re.S)

1.re.match函數

嘗試從字符串的起始位置匹配一個模式,若是不是起始位置匹配成功的話,match()就返回none。
語法:re.match(pattern, string, flags=0)

#示例:
>>> import re
>>> obj = re.match('\d+', '123uuasf')
>>> print(obj.group())
123

2.匹配對象方法

1.group()	  匹配的整個表達式的字符串
2.group(1)    第一個匹配的()中的值
3.groupdict() 返回以有別名的組的別名爲鍵、以該組截獲的子串爲值的字典
  例:print(re.search("(?P<zyl>[0-9]{2})(?P<zz>\d+)","1234567").groupdict())
  結果:{'zyl': '12', 'zz': '34567'}
4.start()	返回匹配開始的位置
5.end()	    返回匹配結束的位置
6.span()	返回一個元組包含匹配(開始,結束)的位置

3.re.search方法

掃描整個字符串並返回第一個成功的匹配。
#示例1:
>>> print(re.search('com','www.baidu.com').group())
com

#示例2:
>>> line = "Cats are smarter than dogs";
>>> searchobj=re.search(r'(.*re)(.*)(th.*)',line)   ##默認貪婪
>>> print(searchobj.group(2))
 smarter

4.re.sub方法

##替換字符串中的匹配項。
語法: re.sub(pattern, repl, string, count=0, flags=0)
#示例1:
>>> s='2017/19/31'
>>> print(re.sub('(\d+)/(\d+)/(\d+)',r'\3-\2-\1',s))
31-19-2017


#示例2:
>>> re.sub("[0-9]+",'|',"aaa234aa111sfaf")
'aaa|aa|sfaf'

pattern : 正則中的模式字符串。         
repl : 替換的字符串,也可爲一個函數。    
string : 要被查找替換的原始字符串。     
count : 模式匹配後替換的最大次數,默認0表示替換全部的匹配。

5.findall

在字符串中找到正則表達式所匹配的全部子串,並返回一個列表,若是沒有找到匹配的,則返回空列表.match 和 search 是匹配一次而findall匹配全部。
#示例:
>>>print(re.findall('\d+','zul111zyl111'))
['111', '111']

6.split方法

按照可以匹配的子串將字符串分割後返回列表,它的使用形式以下:
語法:re.split(pattern, string[, maxsplit=0, flags=0])
#示例:
>>> re.split("[0-9]+","aaa234aa111sfaf")
['aaa', 'aa', 'sfaf']
>>> re.split("([0-9]+)","aaa234aa111sfaf")
['aaa', '234', 'aa', '111', 'sfaf']  #保留分隔符

###每日練習 開發一個簡單的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等相似功能偷懶實現),運算後得出結果,結果必須與真實的計算器所得出的結果一致

代碼以下

# Author:ZhuYuLiang
import re
def format_mark(express):
    express = express.replace('+-', '-')
    express = express.replace('-+', '-')
    express = express.replace('++', '+')
    express = express.replace('--', '+')
    express = express.replace('*+', '*')
    express = express.replace('+*', '*')
    express = express.replace('+/', '/')
    express = express.replace('/+', '/')
    return express

def Add_and_Sub(value):
    expr = value
    sub_expr = re.search(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", expr)
    if not sub_expr:
        return expr
    else:
        sub_expr2 = sub_expr.group()
        if len(sub_expr2.split('+')) > 1:
            n1, n2 = sub_expr2.split('+')
            result = float(n1) + float(n2)
        else:
            n1, n2 = sub_expr2.split('-')
            result = float(n1) - float(n2)
        re_sub_expr = re.sub(r"\-?\d+\.?\d*[\+\-]\d+\.?\d*", str(result), expr, count=1)
        bb = Add_and_Sub(str(re_sub_expr))
        return bb
def Multiplication_and_division(value):
    expr = value
    sub_expr = re.search(r"\d+\.?\d*[\/\*]\-?\d+\.?\d*", expr)
    if not sub_expr:
        return expr
    else:
        sub_expr2 = sub_expr.group()
        if len(sub_expr2.split('/')) > 1:
            n1, n2 = sub_expr2.split('/')
            result = float(n1) / float(n2)
        elif len(sub_expr2.split('*')) > 1:
            n1, n2 = sub_expr2.split('*')
            result = float(n1) * float(n2)
        else:
            # 只計算乘除,加減直接pass,放入加減函數執行
            pass
        re_sub_expr = re.sub(r"\d+\.?\d*[/\*]\-?\d+\.?\d*", str(result), expr, count=1)
        # 反覆調用除法
        bb = Multiplication_and_division(format_mark(re_sub_expr))
        return bb

def compute(value):
    value=Multiplication_and_division(format_mark(value))
    value=Add_and_Sub(format_mark(value))
    return value

def del_brackets(value):
    sub_expr=re.search('\([^()]+\)',value)
    if not sub_expr:
        return value
    else:
        sub_expr=sub_expr.group()[1:-1]
        sub_expr=compute(sub_expr)
        sub_expr3 = re.sub('(\([\+\-\*\/\.0-9]+\))', str(sub_expr), value, count=1)
        delkuohao_expr=del_brackets(format_mark(sub_expr3))
        return delkuohao_expr

if __name__ == '__main__':
    while True:
        express=input('>>: ').replace(' ','')
        print('eval輸出值: ',eval(express))
        if not express:
            continue
        elif express == 'q':
            exit()
        elif re.search('[^0-9.+\-*/()]',express):
            print('\033[31;1m輸入錯誤\033[0m')
        else:
            express=del_brackets(express)
            express2 = compute(format_mark(express))
            print('公式輸出值: ',express2)
相關文章
相關標籤/搜索