python day 8 2019/10/11 資料來自老男孩教育 [TOC] 1. re模塊補充 2. import模塊導入 import是導入模塊的關鍵字。 模塊分為三類:內置模塊,標準模塊,第三方模塊。 模塊的導入路徑是sys.path中的各個元素,python解釋器去sys.path的各個路 ...
目錄
python day 8
2019/10/11
資料來自老男孩教育
1. re模塊補充
import re
data = 'hello my name is lanxing and hello 30, i am very pleased to meet you guys.'
# 從頭匹配:match(pattern, string, flags=0) flags:I(忽略大小寫),M(多行),S(.能匹配所有包括換行符),X(忽略pattern的註釋)
# 無分組的情況下
ret = re.match('h\w+', data) # 匹配成功返回匹配對象,具有以下的group方法,不成功則返回None,不具有下列方法
print(ret.group()) # group方法返回匹配到的所有字元串
print(ret.groups()) # groups方法返回匹配結果中的分組結果,以元組形式將分組結果進行展示
print(ret.groupdict()) # groupdict方法返回匹配結果的分組中所有執行了key的組。
'''
hello
()
{}
'''
# 有分組的情況下:
ret2 = re.match('(?P<n1>h)(?P<name2>\w+)', data) # ?P<n1>是給分組起了個名字叫n1,這個組的key就是n1,後面可以通過這個key來引用這個分組結果。
print(ret2.group()) # group方法返回匹配到的所有字元串,返回結果是一個字元串
print(ret2.groups()) # groups方法返回匹配結果中的分組結果,將每一個分組結果作為元組的元素進行返回。
print(ret2.groupdict()) # groupdict方法返回匹配結果的分組中所有執行了key的組。是一個字典
'''
hello
('h', 'ello')
{'n1': 'h', 'name2': 'ello'}
'''
# search(pattern,str,flags=0),搜索整個字元串,匹配出現的第一個pattern
ret3 = re.search('H(\w+).*(?P<num>\d)', data,flags=re.I) # 不加原生字元串標誌r,就需要再加一個python轉義符\
print(ret3.group()) # group方法返回匹配到的所有字元串,返回結果是一個字元串
print(ret3.groups()) # groups方法返回匹配結果中的分組結果,將每一個分組結果作為元組的元素進行返回。
print(ret3.groupdict()) # groupdict方法返回匹配結果的分組中所有執行了key的組。是一個字典
'''
hello my name is lanxing and hello 30
('ello', '0')
{'num': '0'}
'''
#findall(pattern,str,flags=0),搜索整個字元串,匹配符合pattern的所有字元,並返回一個列表
#1,無分組的情況下,以列表返回所有符合pattern的匹配結果,且匹配結果是不可重疊的。
ret4 = re.findall('\d+\w\d+','a2b3c4d5') # Return a list of all non-overlapping matches in the string
print(ret4)
ret5 = re.findall('','a2b3c4d5') # 匹配結果為空也會包含在列表中。
print(ret5)
# ['', '', '', '', '', '', '', '', '']
# 2,只有一個分組的情況下,會將groups元組裡面的元素單獨拿出來,作為列表的元素進行返回。
n = re.search('h(?P<name1>\w+).*\d','abhw23, hel54')
print(n.group()) # hw23, hel54
print(n.groups()) # ('w23',)
n1 = re.findall('h(?P<name1>\w+).*\d','abhw23, hel54')
print(n1) # ['w23']
#3,超過1個分組的情況下,優先返回分組的匹配結果,即將groups的結果放進列表中進行返回,給分組起別名在findall中是沒用的。。
ret6 = re.findall('h(?P<name1>\w+).*(\d)','abhw23, hel54')
print(ret6) #[('w23', '4')]
ret7 = re.findall('h(\w+(d)).*(\d)','abhwd23, hel54') #每一個括弧的內容都作為元組的元素,該元組再作為列表的元素返回。
print(ret7) #[('wd', 'd', '4')]
# #搜索整個字元串,匹配符合pattern的字元串,並返回一個迭代器
ret8= re.finditer('h(\w+(?P<name1>d)).*(\d)','abhwd23, hel54')
print(ret8)
for i in ret8:
print(i,i.group(),i.groups(),i.groupdict(),sep='\n')
# <callable_iterator object at 0x0000017BED3A8DA0>
# <re.Match object; span=(2, 14), match='hwd23, hel54'>
# hwd23, hel54
# ('wd', 'd', '4')
# {'name1': 'd'}
m1 = re.findall('(\w)(\w)(\w)(\w)','hello') #以實際分組有多少個,列表中的嵌套元組才會有多少個元素。
print(m1) #[('h', 'e', 'l', 'l')]
m2 = re.findall('(\w){4}','hello') #如果分組實際顯示的只有一個,則預設匹配最後一次符合要求的字元串
print(m2) #['l']
m3 = re.findall('(\w)*','hello') #因為貪婪匹配預設匹配多個,而*是代表可有可無,所以匹配到o時,*代表pattern是None,再匹配一次。返回空值。
print(m3) # ['o', '']
m4 = re.findall('(\dasd)*','1asd2asdp3asd98132') #輪到p的時候,*為0的情況出現了,意味著pattero為None。到98132時,*為0的情況也出現了,都返回空值。
print(m4)
m5 = re.findall('(\dasd)+','1asd2asdp3asd98132') #如果是+就不會出現這種情況了。即有數量表示符*,+,{m,n}的情況預設匹配最後一次符合pattern的字元串。
print(m5)
#re.split(pattern, string, maxsplit=0, flags=0),首先是找到所有的匹配字元,再根據匹配字元進行分割並返回列表,如果有分組情況,則分組的結果也將在列表中。
# 1,無分組的情況下:
data = 'hello my name is lanxing and hello 30, i am very pleased to meet you guys.'
print( re.findall('m\w',data) ) # ['my', 'me', 'me']
li1 = re.split('m\w',data,maxsplit=2) #可以限定將findall中的多少個元素作為分割元素。
print(li1) # ['hello ', ' na', ' is lanxing and hello 30, i am very pleased to meet you guys.']
# 2,有分組的情況下:
print( re.findall('m(\w)',data) )
li2 = re.split('m(\w)',data,1) # 會將分組內容提取出來,並作為元素返回在列表中
print(li2)
#sub(pattern, repl, string, count=0, flags=0),將匹配內容進行替換,count如果是0代表替換所有的匹配內容。
print(re.sub('\d','kk','1as23fe')) #返回替換後的字元串
print(re.subn('\d','kk','1as23fe')) #返回一個元組 ('kkaskkkkfe', 3),替換了3次
# 1 - 2 *((60-30+(-40.0/5)*(9-2*5/3 +7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))
# 首先匹配最裡層的括弧,算出其值,再匹配外面一層的括弧
num = '1 - 2 *((60-30+(-40.0/5)*(9-2*5/3 +7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2)) '
# match2 = re.findall(r'\([^()]+\)',num)
# print(eval(match2[0]))
# print(match2)
# match1 = re.split(r'\(([^()]+)\)',num,1) #轉義括弧,分組括弧,分組括弧中的匹配會在分割列表中保留
# print(match1)
while True:
print(num)
result = re.split(r'\(([^()]+)\)',num,maxsplit=1) #按照第一次出現的最裡層的括弧進行切割,最裡層括弧的內容作為分組結果保留在列表中
if len(result)==3: #等於3代表有括弧
before = result[0] # 第一次出現最裡層括弧前面的字元串
content = result[1] #第一次出現最裡層括弧中的字元串
after = result[2] # 第一次出現最裡層括弧後面的字元串
new_content = eval(content)
print(new_content,type(new_content))
num = ''.join([before,str(new_content),after]) #通過eval函數計算出來的結果,再與前後括弧的內容進行拼接,並賦值給變數num,這樣num就變成了少了一層括弧的新字元串了
else:
final = eval(num)
print(final)
break
2. import模塊導入
import是導入模塊的關鍵字。
模塊分為三類:內置模塊,標準模塊,第三方模塊。
模塊的導入路徑是sys.path中的各個元素,python解釋器去sys.path的各個路徑去搜索,如果有這個模塊則導入成功。
import modulename
表示導入某個模塊。
from package import modulename as bbb
表示從某個庫中導入某個模塊,並將模塊起別名叫bbb,後面使用就用bbb來代替modulename了。儘量使用from來導入模塊。
from package import *
表示導入所有的內容。
3. os模塊
sys模塊是關於python解釋器的模塊,而os模塊是關於操作系統功能的模塊。
import os
current_dir = os.getcwd() #獲取當前工作目錄,即當前python腳本工作的絕對目錄路徑。
print(current_dir)
# os.chdir('..') #改變當前腳本工作目錄,相當於shell下的cd,接一個目錄作為參數,可以是相對路徑,也可以是絕對路徑。
print(os.curdir) # 返回當前目錄的字元串名:('.')
print(os.pardir) #返回當前目錄的父目錄字元串名:('..')
#os.makedirs(path,mode,exist_ok=False)
# os.makedirs('dir/dir2') #可生成多層遞歸目錄,如果不是絕對路徑,則預設在當前目錄下創建目錄。
# os.removedirs('dir/dir2') #若目錄為空,則移除,並遞歸到上一層目錄,如若也空,則刪除,依此類推
# os.mkdir('dir') #創建單層目錄,如果不是絕對路徑,則預設在當前目錄下創建目錄
# os.rmdir('dir') #刪除單級空目錄,若目錄不為空則無法刪除,報錯;相當於shell中rmdir dirname
print(os.listdir('dir')) #列出指定目錄下的所有文件和目錄,包括隱藏文件,並以列表形式返回
# os.remove('dir/New Text Document.txt') #刪除指定文件
#os.rename('oldname','newname') 重命名文件/目錄
print(os.stat('dir')) #獲取文件/目錄信息
print(os.sep) #獲取操作系統特定的路徑分隔符,window是\\,linux是/
print(os.linesep) #當前平臺使用的行終止符,win下為'\r\n',linux下為'\n'
print(os.pathsep) #用於分割文件路徑的字元串,即';'
print(os.name) #顯示當前使用平臺,win下是nt,linux下是posix
os.system('dir') #運行shell命令,直接顯示
# print(os.environ) #獲取系統環境變數
print(os.path.abspath('../..') ) #返回指定路徑的絕對路徑,一般參數是相對路徑如'.','..'
path_list = os.path.split(r'F:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
print(path_list) #將path分割成目錄和文件名二元組返回
abs_par_path=os.path.dirname(r'F:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
#返回指定目錄的上一級目錄的絕對路徑值,其實就是split的第一個元素
os.path.basename(r'F:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
#返回給定路徑的文件名,如果path以/或\\結尾,則返回空值,就是split的第二個元素。
os.path.exists(r'F:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day8_os\osmodule.py')
#如果給定路徑存在,則返回True,否則是False
os.path.isabs(r'F:dsaf/adf')
#如果給定路徑是絕對路徑,則返回True.
os.path.isfile(r'f:\13.txt') #如果路徑是一個存在的文件,返回True
os.path.isdir(r'f:/test1') #如果路徑是一個存在的文件夾,返回True
print(os.path.join('f:','test1','test2','123.txt')) #將路徑拼接在一起,形成一個目錄。f:test1\test2\123.txt
time1 = os.path.getatime(r'F:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day3\int_str_set.py')
#返回path所指向的文件或者目錄的最後存取時間戳
import time
print(time.ctime(time1))
time2= os.path.getmtime(r'F:\github\thestudyofpython\studyofpython\pycharm_lanxing\learn_python_from_oldboy\day3\int_str_set.py')
print(time2)
# 返回path所指向的文件或者目錄的最後修改時間戳
4. hashlib模塊
用於加密相關的操作,代替了md5模塊和sha模塊,主要提供SHA1,SHA224,SHA256,SHA384,SHA512,MD5演算法.
現在常用是MD5與SHA256.
import hashlib
# md5演算法
'''
- update(data): Update the hash object with the bytes in data. Repeated calls
are equivalent to a single call with the concatenation of all
the arguments.
- digest(): Return the digest of the bytes passed to the update() method
so far as a bytes object.
- hexdigest(): Like digest() except the digest is returned as a string
of double length, containing only hexadecimal digits.
- copy(): Return a copy (clone) of the hash object. This can be used to
efficiently compute the digests of datas that share a common
initial substring.
'''
hash1 = hashlib.md5() #創建一個md5的哈希對象
hash1.update(bytes('lanxing',encoding='utf-8')) #update方法是使用位元組類型數據去更新哈希對象
print(hash1,type(hash1))
print(hash1.digest(),type(hash1.digest())) #返回哈希對象的位元組類型摘要
print(hash1.hexdigest()) #返回十六進位的哈希值
hash2 = hashlib.sha256()
hash2.update(bytes('lanxing',encoding='utf-8'))
print(hash2.hexdigest())
# 59b304df8872f6f0443d389574796e65160c8a8b4df6073e20168ae82a73187a
hash3 = hashlib.sha256(bytes('lanxing',encoding='utf-8')) #創建一個sha256的哈希對象,其鹽是lanxing
hash3.update(bytes('lanxing',encoding='utf-8')) #加鹽之後,原先對應的哈希值就不一樣了。可以防止別人撞庫。
print(hash3.hexdigest())
# 590ec4accc861c0feb928f62c221f5b943e17aeda50e43d6d894050cf42de48e
import hashlib
def register(username,passwd):
'''
register a new account to the database
:param username: username , a str
:param passwd: password, a str
:return: True
'''
with open('accounts.db','a+',encoding='utf-8') as f:
ret = hash_passwd(passwd)
account = '\n'+username+'$'+ret
f.write(account)
f.flush()
return True
def login(username,passwd):
'''
check the account to see if they match the account in the database
:param username: username,a str
:param passwd: password,a str
:return: True if matched,False if not.
'''
with open('accounts.db','r',encoding='utf-8') as f:
for line in f:
data = line.split('$')
ret = hash_passwd(passwd)
if data[0]==username and ret == data[1]:
return True
def hash_passwd(passwd):
'''
change the passwd to hexdigest of hash object
:param passwd: a str
:return: hexdigest
'''
hash1 = hashlib.sha256(bytes('lanxing', encoding='utf-8'))
hash1.update(bytes(passwd, encoding='utf-8'))
return hash1.hexdigest()
if __name__=='__main__':
username = input('enter your name:>>>').strip()
passwd = input('enter your passwd').strip()
choice = input('1 to register or 2 to log in:>>>').strip()
if choice == '1':
register(username,passwd)
print('註冊成功')
elif choice=='2':
if login(username,passwd):
print('登錄成功')
else:
print('登錄失敗')
5. 字元串格式:百分號法與format方法
百分號法是比較老的方式,而format是較新的方法,現在python3中兩者共存。
- 百分號%方法
%[(name)][flags][width].[precision]typecode
,其中name,flags,width,precision都是可選的。
name表示key,後面可以通過key:value的形式進行引用。
flags與width經常一起用:
flags表示左右對齊,值有+表示右對齊,空格表示右對齊,-表示左對齊,0表示右對齊,用0補充不足寬度處。
width表達寬度,一般用不著。值是數字。
precision表示精度,值是數字。
typecode常用s(表示字元串),d(表示整數),f(表示浮點數)。必選參數。
如果字元串中有占位符%,要想表示原生的%,必須使用兩個%。'%% %.2f' % 3.689
s='i am %(name)s, and my age is %(age)d'%{'name':'lanxing','age':19}
print(s)
# i am lanxing, and my age is 19
s1 = 'i am %(name)+10s, and my age is %(age).2f'%{'name':'lanxing','age':19.6789}
print(s1)
# i am lanxing, and my age is 19.68
- format方法
[[fill]align][sign][#][0][width][,][.precision][type]
參數介紹:
s1 = ' i am {},age {},sex {}'.format('lanxing',18,'male')
s2 = 'i am {},age {},sex {}'.format(*['lanxing',18,'male'])
s3 = 'i am {0},age{1},really {0}'.format('rich',19) #format參數的索引值,從0開始
s4 = 'i am {0},age{1},really {0}'.format(*('rich',18))
s5 = 'i am {name},age{age},reall {name}'.format(name='rich',age=18)
s6 = 'i am {name},age{age},reall {name}'.format(**{'name':'rich','age':18})
s7 = 'i am {0[0]},age {0[1]},really{0[2]}'.format([11,22,33],[44,55,66])
s8 = 'i am {:s},age {:d},money {:.2f}'.format('lanxing',18,2689.222)
s9 = "i am {name:s}, age {age:d}".format(**{"name": "seven", "age": 18})
s10 = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2)
s11 = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15)
s12 = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
6. 模塊知識拾遺
# print(vars())
'''
__name__
__loader__
__doc__
__package__
__spec__
__file__
__builtins__
__cached__
'''
print(__name__) #如果是主文件,__name__==‘__main__',如果是其他文件,則是他的模塊名
import str_format as sf
print(sf.__name__)
print(__doc__) #自身py文件的多行註釋
print(sf.__package__ ) #導入py文件所在的文件夾,用.劃分文件夾,當前文件是None
print(__file__) #本身自己文件的絕對路徑
print(sf.__cached__) #緩存:緩存,當前文件沒有,導入其他文件才有
# 只有執行自身時,__name__=='__main__',否則等於其模塊名,以後主程式都要先加個條件,這樣別人導入時,就不會自動執行了。
if __name__=='__main__':
a = 1
#將某個文件夾路徑放入sys.path中,且不怕父文件夾改名
import os,sys
if __name__=='__main__': #主文件執行時,一定要寫這個
dir1=os.path.dirname(__file__) #__file__一定要記住是文件自身的絕對路徑
dir2 = os.path.dirname(dir1) #某個路徑的上層目錄
s1 = 'day7_time_sys'
dir3 =os.path.join(dir2,s1) #將路徑拼接在一起
print(dir3)
sys.path.append(dir3) #將某個路徑追加到python解釋器的模塊搜索路徑列表中去
import jsonmodule
- 安裝第三方模塊
使用pip安裝:
第一步:先下載pip。
第二步:將pip的bin目錄添加到環境變數中。
第三步:在cmd中運行 pip install modulename
。
源碼安裝:
第一步:先下載源碼。
第二步:解壓縮源碼。
第三步:在cmd中進入源碼目錄。
第四步:cmd中執行python setup.py install
。
7. requests模塊初識
urllib,requests是發起http請求,獲得請求返回值的模塊。
import requests,json
# requests模塊,發送http請求,(用python模擬瀏覽器請求)
response = requests.get('https://www.cnblogs.com/wupeiqi/articles/5484747.html')
# 向指定網址發送請求,返回一個requests.models.Response對象
response.encoding = 'utf-8' #將請求對象的編碼設置為utf8
result =response.text #text就是請求對象的內容,是一個str類型
# result = json.loads(result) #會報錯
print(type(response),result,type(result),sep='\n')