模塊

模塊

#什麼是模塊
	模塊就是一系列功能的結合體

#模塊的三種來源
	1.內置模塊	(python解釋器自帶的)
    2.第三方模塊	(別人寫的,requests)
    3.自定義模塊	(本身寫的)
    
#模塊的四種表現形式
	1.使用python編寫的py文件(一個py文件也能夠成爲一個模塊)
    2.已被編譯爲共享庫或DLL的C或C++擴展
    3.把一系列模塊組織到一塊兒的文件夾(文件夾下有一個__int__.py文件,該文件夾稱之爲包,包就是一系列py文件的集合體)
    4.使用C編寫,並鏈接到python解釋器的內置模塊
    
#爲何用模塊
	1.用別人寫好的模塊(內置的、第三方的),能夠拿來就用,極大地提升開發效率
    2.使用本身寫的模塊(自定義的)
    	當程序比較大的時候,全部項目不可能只在一個py文件中
        當多個文件中都須要使用相同的方法的時候,能夠將該公共的方法寫到一個py文件中
        其餘的文件以模塊的形式導過去直接調用便可
        達到減小代碼冗餘的目的
    3.項目結構更加清晰

#怎麼用模塊
 	注意,必定要區分哪一個是執行文件,哪一個是被執行文件(導入文件)
    使用關鍵字import導入模塊
    import md,模塊名(文件名)叫md.py,可是導入的時候只須要寫md,不要加.py後綴
    屢次導入一個模塊文件,只有第一次有效

#執行文件的流程
	鼠標右鍵運行a.py文件
    首先會建立一個a.py的名稱空間
	若是import導入模塊(md.py):
    	1.執行模塊文件md.py,運行模塊文件md.py中的代碼
        2.將產生的名字與值存放到該模塊文件的名稱空間中
        3.在執行文件a.py中,定義一個變量名md,指向md.py的名稱空間
        
#使用import導入模塊
	#0.訪問該模塊名稱空間中的變量名的統一句式爲:模塊名.變量名
import md
	#1.指名道姓的訪問模塊中的名字,永遠不會與執行文件中的名字衝突
print(md.x)
	#2.只要能拿到函數名,不管在哪均可以經過函數名加括號來調用這個函數(調用函數,會回到函數定義階段,依次執行代碼)
	#3.函數在定義階段,名字的查找順序就已經固定死了,不會由於調用位置的改變而改變
print(md.read1)		#<function read1 at 0x000001EBC20AFF28>
md.change()
	
#可使用import一次導入多個模塊,可是不推薦使用(會致使代碼的結構不清晰)
	#只有當幾個模塊有相同部分或者屬於一個模塊,能夠一次導入
    #當幾個模塊沒有聯繫的狀況下,應該分屢次導入
    #一般導入模塊的句式會寫在文件開頭
import md,time,os
import md
import time
import os

#當模塊名比較複雜的時候能夠給模塊起別名
import testtttttttttttttttt as test

#from ... import ...
	#屢次導入,只有第一次有效
from md import x
from md import x
    #只會導入該模塊的指定的一個變量名,不會導入別的變量名
    #訪問模塊中的名字,不須要加模塊名前綴(當心覆蓋當前名稱空間中的變量名)
print(x)
	#from md import *一次性將md模塊中的變量名所有加載(不推薦使用,佔用內存)
    #__all__能夠指定當前所在py文件被當作模塊導入的時候,執行文件使用*,能夠拿到的變量名(__all__ = ['x']),默認x爲*
from md import *
print(x)
print(y)		#NameError: name 'y' is not defined

循環導入

#循環導入問題
	#若是程序出現循環導入問題,那麼必定是程序設計的不合理
    #循環導入問題在程序設計階段就應該避免

m1.py文件
from m2 import y		#第一次導入(導入、執行代碼,但不執行函數)
print('正在導入m1')
x = 1

m2.py文件
from m1 import x		#第二次導入,此事x未定義
print('正在導入m2')
y = 2

a.py文件
import m1		#ImportError

#解決循環導入問題的方式:
	#1.方式1
    	將循環導入的句式寫在文件最下方 
m1.py文件
print('正在導入m1')
x = 1
from m2 import y

m2.py文件
print('正在導入m2')
y = 2
from m1 import x
    
    #2.方式2
     	在函數內導入模塊
m1.py文件
print('正在導入m1')
def f1():
    from m2 import y		#第一次導入
    print('m1,f1>>>y')
x = 1

m2.py文件
print('正在導入m2')
def f2():
    from m1 import x		#第二次導入,此時x已經定義
    print('m2,f2>>>x')
y = 2

import m1
m1.f1()

正在導入m1
正在導入m2
m1,f1>>>y
	#3.方式3
    	從新設計項目,拆分循環導入的代碼

__name__能夠區分py文件

#當文件被當作執行文件執行的時候,__name__打印的結果是__main__
#當文件被當作模塊導入的時候,__name__打印的結果是被執行文件名(沒有後綴)

def f1():
    print('f1')
def f2():
    print('f2')
f1()
f2()
print(__name__)

f1
f2
__main__/m1

#使用__name__,測試自定義模塊功能
def f1():
    print('f1')
def f2():
    print('f2')
if __name__ == '__main__':		(快捷寫法,main+TAB)
    f1()
    f2()

模塊的查找順序

# 模塊的查找順序
	1.先從內存中找
    2.再從內置模塊中找
    3.再從sys.path中找(至關於當前文件的環境變量)
    
#模塊sys
	#sys.path就是一個大列表,裏面放了一堆文件路徑,第一個路徑永遠是執行文件所在的文件夾
import sys
print(sys.path)		#['E:\\python_test', 'E:\\python_test', 'C:\\Program Files\\JetBrains\\PyCharm 2020.1.3\\plugins\\python\\helpers\\pycharm_display', 'C:\\Users\\17575\\AppData\\Local\\Programs\\Python\\Python36\\python36.zip', 'C:\\Users\\17575\\AppData\\Local\\Programs\\Python\\Python36\\DLLs', 'C:\\Users\\17575\\AppData\\Local\\Programs\\Python\\Python36\\lib', 'C:\\Users\\17575\\AppData\\Local\\Programs\\Python\\Python36', 'C:\\Users\\17575\\AppData\\Roaming\\Python\\Python36\\site-packages', 'C:\\Users\\17575\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages', 'C:\\Users\\17575\\AppData\\Local\\Programs\\Python\\Python36\\lib\\site-packages\\pip-20.2.3-py3.6.egg', 'C:\\Program Files\\JetBrains\\PyCharm 2020.1.3\\plugins\\python\\helpers\\pycharm_matplotlib_backend']

#驗證查找順序  -- 先從內存中找
	1.鼠標右鍵運行
    2.刪除f1()
import time
import m1
time.sleep(10)
m1.f1()

#驗證查找順序  -- 從內置模塊中找
	1.鼠標右鍵運行
    2.能夠看到,導入了內置模塊
import time
print(time.time())		#變量名應該避免與模塊名衝突

#驗證查找順序  -- 從sys.path中找(執行文件所在文件夾)
	當執行文件所在文件夾下,存在該文件時,直接導入
	當執行文件所在文件夾下,不存在該文件時(#不會查找目錄)
    	可使用from dir import xx,from dir.dir1.dir2 import xx導入指定文件
        把被執行文件夾添加到環境變量,再導入(#項目文件夾)
        import sys
        sys.path.append(r'E:\python_test\m1.py')
        import m1

#注意
	1.文件名不該該與模塊名(內置、第三方)衝突

相對導入(相對路徑)

#相對導入不能在被執行文件中使用,能夠在被導入文件中使用 (模塊文件)    
	#相對導入不須要考慮絕對路徑,只須要知道與被導入文件的兩個路徑之間的關係便可
    
#點
	.		當前路徑
    ..		上一級路徑
    ...		上上一級路徑

絕對導入(絕對路徑)

#絕對路徑不管在執行文件仍是被執行文件中都適用
	#絕對導入必須依據執行文件所在的文件夾路徑爲基準   
    #通常狀況下,一個項目只會有一個執行文件,其餘文件都是模塊,因此相對導入的的應用是很普遍的

軟件開發目錄規範

#優勢
	1.項目結構更加清晰
    2.便於管理
    3.擴展性高

#start.py(啓動文件,該文件能夠放到項目根目錄下)
import os
import sys
BASE_dir = os.path.dirname(os.path.dirname(__file__))
sys.path.append(BASE_dir)
from core import src
if __name__ == '__main__':
    src.run()
    
#settings.py(配置文件)
	#把一個目錄放到環境變量裏面,那麼,該目錄下的文件可使用相對路徑導入
    #若是項目目錄就是一級目錄(頂級目錄),那麼不須要把該目錄添加到環境變量(pycharm自動添加)
    #不要使用%s拼接路徑,要使用os模塊,以適用於把不一樣的用戶
    #添加環境變量的操做盡可能保留,以適用於不一樣的系統
import os
BASE_dir = os.path.dirname(os.path.dirname(__file__))
LOG_path = os.path.join(BASE_dir,'log')

#src.py(核心文件)
from lib import comman
db_username = 'syy'
db_password = 123
user_dic = {
    'is_login':None
}
@comman.login_auth
def register():
    print('reigster')
def login():
    while True:
        username = input('請輸入用戶名>>>: ').strip()
        password = int(input('請輸入用戶密碼>>>: ').strip())
        if username == db_username and password == db_password:
            user_dic['is_login'] = True
            run()
        else:
                print('輸入錯誤,請從新輸入')
def shopping():
    print('shopping')
def transfer():
    print('transfer')
@comman.login_auth
def pay():
    print('pay')
def withdraw():
    print('withdraw')
@comman.login_auth
def pay_bak():
    print('pay_bak')
def check_record():
    print('check_record')

my_dict = {
    '1':register,
    '2':login,
    '3':shopping,
    '4':transfer,
    '5':pay,
    '6':withdraw,
    '7':pay_bak,
    '8':check_record
}
def run():
    while True:
        print("""
        1  register(註冊)
        2  login(登陸)
        3  shopping(購物)
        4  transfer(轉帳)
        5  pay(支付)
        6  withdraw(提現)
        7  pay_bak(還款)
        8  check_record(查看流水)
        """)
        choice = input('please choice func to operate>>>: ').strip()
        if choice not in my_dict:
            print('相關功能還在開發中')
        my_dict.get(choice)()
        break
        
#comman.py(公共的功能)
from core import src
def login_auth(func):
    def inner(*args,**kwargs):
        if src.user_dic.get('is_login'):
            res = func(*args,**kwargs)
            return res
        else:
            print('請先登陸')
            src.login()
    return inner

#Readme.py
對這款軟件的介紹
    本軟件是一個結合了ATM+購物的一個多功能的購物應用程序
    用戶能夠經過bin目錄下的啓動程序啓動程序
    
#db文件夾下面的userinfo.py(數據庫數據)
#log文件夾下面的文件(日誌)

正則

正則表達式匹配手機號html

正則表達式匹配身份證號python

#正則
	在編寫處理字符串的程序或網頁時,常常有查找符合某些複雜規則的字符串的須要。正則表達式就是用於描述這些規則的工具。換句話說,正則表達式就是記錄文本規則的代碼。
	正則就是篩選字符串中的特定的內容的規則的代碼
    接觸到的,以reg開頭的單詞,一般與正則有關(正則測試:http://tool.chinaz.com/regex)
    正則表達式默認都是貪婪匹配,能夠經過在量詞的後面加上一個?,就能夠將貪婪匹配變成非貪婪匹配(惰性匹配)

#正則的應用場景(推薦: 《正則指引》)
	爬蟲
    數據分析
    
#普通的python腳本
while True:
    phone_number = input('please input your phone number>>>: ').strip()
    if len(phone_number) == 11 \
        and phone_number.isdigit() \
        and (phone_number.startswith('13') \
            or phone_number.startswith('14')
            or phone_number.startswith('15')
            or phone_number.startswith('16')
            or phone_number.startswith('17')
            or phone_number.startswith('18')
            ):
        print('手機號合法')
    else:
        print('輸入的手機號不合法')
        
#使用re模塊寫的python腳本
import re
while True:
    phone_number = input('please input your phone number>>>: ').strip()
    if re.match('^(13|14|15|16|17|18)[0-9]{9}$',phone_number):
        print('手機號合法')
    else:
        print('輸入的手機號不合法')
        
import re
while True:
    phone_number = input('please input your phone number>>>: ').strip()
    if re.match('^1(?:3\d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8\d|9\d)\d{8}$',phone_number):		#?:將貪婪匹配變成非貪婪匹配
        print('手機號合法')
    else:
        print('輸入的手機號不合法')   
        
#身份證號碼
	身份證號碼是一個長度爲15或者18個字符的字符串
    	若是是15位,則所有由數字組成,而且首位不能爲0 
        若是是18位,則前17位所有都是數字,末位多是數字,也多是X
        
import re
while True:
    phone_number = input('please input your phone number>>>: ').strip()
    if re.match('\^[1-9]\d{14}(\d{2}[0-9x])?$\',phone_number):
        print('身份證號碼合法')
    else:
        print('身份證號碼不合法') 
                
import re
while True:
    phone_number = input('please input your phone number>>>: ').strip()
    if re.match('^[1-9]\d{16}[0-9x]|^[1-9]\d{14}$',phone_number):
        print('身份證號碼合法')
    else:
        print('身份證號碼不合法')

經常使用元字符git

代碼 說明
. 匹配除換行符之外的任意一個字符
\w 匹配字母或數字或下劃線、漢字(w是word的縮寫)
\s 匹配任意的空白符(space)(空格或TAB鍵,不包括換行符)
\d 匹配數字(digit)
N\b 匹配單詞的結束
^N 匹配字符串的開始(相似於startswith)
N$ 匹配字符串的結束(相似於endswith)
\n 匹配一個換行符
\t 匹配一個製表符
a|b 匹配字符a,或者字符b (注意ab|abc匹配abc是ab的做用,abc|ab是abc的做用)
() 匹配括號內的表達式,也表示一個組,使用.group()訪問組匹配

分組:當多個正則符號須要重複屢次的時候,或者當作一個總體進行其餘操做,那麼就要使用分組,分組使用一對括號() 表示正則表達式

經常使用限定符 (量詞)算法

代碼/語法 說明
* 當前字符重複零次或更屢次(a*b)
N+ 左邊字符重複一次或更屢次(貪婪匹配),N+? (惰性匹配)
N? 左邊字符重複零次或一次
N{n} 重複n次
N{n,} 重複n次或更屢次
N{n,m} 重複n到m次(貪婪匹配),N{n,m}? (惰性匹配)

量詞中的多:貪婪匹配,儘可能匹配知足條件的最多的字符,能夠經過在量詞的後面加上一個?,就能夠將貪婪匹配變成非貪婪匹配(惰性匹配)shell

量詞中的少:量詞只做用於左邊的第一個字符,也就是說只能跟在字符的後面數據庫

經常使用反義詞編程

代碼/語法 說明
\W 匹配任意不是字母,數字,下劃線,漢字的字符
\S 匹配任意不是空白符的字符
\D 匹配任意非數字的字符
\B 匹配不是單詞結束的單詞
[^x] 匹配除了x之外的任意字符
[^aeiou] 匹配除了aeiou這幾個字母之外的任意字符

轉義符json

正則 待匹配字符 解釋
'\n' 匹配一個換行符
'\\n' \n 轉義符轉移後面的\
'\\\\n' \\n 轉義符轉移後面的\
r'\\n' \n r,讓整個字符串不轉義

非貪婪匹配 (惰性匹配)數組

正則 解釋
*?、.**? 重複任意次,可是儘量的少重複
N+? 重複一次或更屢次,可是儘量的少重複
?? 重複0次或一次,可是儘量的少重複
N{n,m}? 重複n到m此,可是儘量的少重複
N{n,}? 重複0次以上,可是儘量的少重複

re模塊

#re模塊與正則表達式之間的關係
	正則表達式不是python獨有的,他是一門獨立的技術
    全部的編程語言均可以使用正則
    若是想在python中使用正則,就必須依賴於re模塊,來達到書寫正則表達式目的
    
#re.findall('正則表達式','字符串')
    找到字符串中符合正則表達式的所有內容,返回一個列表,列表中就是正則匹配到的內容
    
import re
res = re.findall('s','syyttsry')
print(res)		#['s', 's']

import re
res = re.findall('k','syyttsry')	
print(res)	#[],找不到的話,返回空列表

import re
res = re.findall('[a-z]','syyttsry')
print(res)		#['s', 'y', 'y', 't', 't', 's', 'r', 'y']
    
import re
res = re.findall('[a-z]+','syyttsry')
print(res)		#['syyttsry']
    
import re
res = re.findall('[a-z]+','syyttsry yys')
print(res)		#['syyttsry', 'yys']
    
#re.search('正則表達式','字符串')
	search會匹配字符串開頭、中間、結尾的部分,只返回找到的第一個單詞
    search不會給你直接返回匹配到的結果,而是給你返回一個對象
    使用.group(),才能看到匹配的結果
    注意,search只會根據正則查找目標一次,找到即停,若是找不到的話,返回None
    
import re
res = re.search('s','syytrihys si op')
print(res)				#<_sre.SRE_Match object; span=(0, 1), match='s'>
print(res.group())		#s

import re
res = re.search('syyi','syytrihys syyi opa')
print(res)				#<_sre.SRE_Match object; span=(10, 14), match='syyi'>
print(res.group())		#syyi

import re
res = re.search('k','syytrihys si op')
print(res)				#None
print(res.group())		#AttributeError,不存在的話(None)直接報錯

import re
res = re.search('k','syytrihys si op')
print(res)
if res:
    print(res.group())
    
#re.match('正則表達式','字符串')
	match只會匹配字符串的開頭,只返回一個
	match不會給你直接返回匹配到的結果,而是給你返回一個對象
    使用.group(),才能看到匹配的結果
    注意,match只會根據正則查找目標一次,找到即停,若是找不到的話,返回None
    
import re
res = re.match('syy','syytrihys si op')
print(res)				#<_sre.SRE_Match object; span=(0, 3), match='syy'>
print(res.group())		#syy

import re
res = re.match('k','syytrihys si op')
print(res)				#None
print(res.group())		#AttributeError

import re
res = re.match('k','syytrihys syyi op')
print(res)
if res:
    print(res.group())		#防止報錯
    
#re.split('正則表達式','字符串')
	切割字符串
    
import re
res = re.split('[ab]','1a2bcd')
print(res)			#['1', '2', 'cd']
import re
res = re.split('(\d)','1a2bcd')
print(res)			#['', '1', 'a', '2', 'bcd'],保留切割的數字

#re.sub('正則表達式','新的內容','字符串',N)
	替換字符

import re
res = re.sub('\d','H','1a2b3c4d',2)
print(res)			#HaHb3c4d

#re.subn('正則表達式','新的內容','字符串',N)
	替換字符
    返回的是一個元組,內容是替換後的字符串和替換的個數
    
import re
res = re.subn('\d','H','1a2b3c4d',2)
print(res)			#('HaHb3c4d', 2)

#re.compile('正則表達式')
	編譯正則表達式
    
import re
obj = re.compile('\d{3}')		#將正則表達式編譯成一個正則表達式對象
res = obj.search('abc123eee111ttt')		#正則表達式對象調用search,參數爲待匹配的字符串
print(res.group())				#123
res = obj.findall('abc123eee111ttt')
print(res)						#['123', '111']

#re.finditer('正則表達式')  
	與findall相似,不一樣點在於結果是一個迭代器
import re
res = re.finditer('\d','1n2j3kL')
print(res)			#<callable_iterator object at 0x000002CF41AFF898>
print(next(res))	#<_sre.SRE_Match object; span=(0, 1), match='1'>
print(next(res))	#<_sre.SRE_Match object; span=(2, 3), match='2'>
print(next(res))	#<_sre.SRE_Match object; span=(4, 5), match='3'>
print(next(res))	#StopIteration

#re模塊中的分組
	findall會優先把匹配結果組裏面的結果返回,若是想要匹配結果,使用?:取消權限便可
import re
res = re.findall('^[1-9]\d{14}(\d{2}[0-9x])?$','94596847739994375x')
print(res)
res = re.findall('^[1-9]\d{14}(?:\d{2}[0-9x])?$','94596847739994375x')
print(res)	
res = re.search('^[1-9]\d{14}(\d{2}[0-9x])?$','94596847739994375x')
print(res)
print(res.group())
print(res.group(1))
res = re.match('^[1-9]\d{14}(\d{2}[0-9x])?$','94596847739994375x')
print(res)
print(res.group())
print(res.group(1))

['75x']
['94596847739994375x']
<_sre.SRE_Match object; span=(0, 18), match='94596847739994375x'>
94596847739994375x
75x
<_sre.SRE_Match object; span=(0, 18), match='94596847739994375x'>
94596847739994375x
75x

#re模塊中的分組與別名(?P<別名>)
import re
res = re.findall('^[1-9]\d{14}(\d{2}[0-9x])?$','94596847739994375x')
print(res)
res = re.search('^[1-9]\d{14}(?P<password>\d{2}[0-9x])?$','94596847739994375x')
print(res)
print(res.group())
print(res.group(1))
print(res.group('password'))
res = re.match('^[1-9]\d{14}(?P<password>\d{2}[0-9x])?$','94596847739994375x')
print(res)
print(res.group())
print(res.group(1))
print(res.group('password'))

['75x']
<_sre.SRE_Match object; span=(0, 18), match='94596847739994375x'>
94596847739994375x
75x
75x
<_sre.SRE_Match object; span=(0, 18), match='94596847739994375x'>
94596847739994375x
75x
75x

正則在爬蟲中的應用

#爬蟲就是爬取網頁的html代碼(就是一堆字符串)
	1.研究網站是否有反爬措施
    2.研究該網站頁面URL的規律
    3.想要什麼內容,寫出對應的正則表達式,爬取代碼
    4.從這一堆字符串中篩選出你想要的的內容

typing模塊

參考網站

#typing模塊
	輸入提示,只會提示
	
from typing import List ,Tuple
def test1(
        name: str,
        age :int,
        balance :float,
        user_info :List
        pawass: tuple
) -> Tuple[int,float,str,list,dict,tuple]:
    return (name ,age ,balance ,user_info)
res = test1('111' ,'2' ,3.3 ,[4,4,4])
print(res)

collection模塊

#python的基本數據類型有整形、浮點型、字符串、列表、元組、字典、布爾值、集合
#collection模塊提供別的數據類型
    namedtuple 	:具名元組,生成使用名字來訪問元素內容的tuple
    deque 		:雙端隊列,能夠快速的從另一側追加和推出對象
    counter 	:計數器,主要用來計數
    ordereddict :有序字典
    defaultdict	:帶有默認值的字典
    
#具名元組,namedtuple('註釋','['']')
from collections import namedtuple
point = namedtuple('座標',['x','y'])		#使用列表(可迭代對象)表示座標
p = point(1,2)	#注意元素數量要保持一致
print(p)		#座標(x=1, y=2)
print(p.x)		#1
print(p.y)		#2
    
from collections import namedtuple		
point = namedtuple('座標','x,y')			#使用字符串表示座標(以空格或逗號分隔)
p = point(1,2)
print(p)
print(p.x)
print(p.y) 

	#打印撲克
from collections import namedtuple
card = namedtuple('撲克牌','color number')
A = card('♠','A')
print(A)
print(A.color)
print(A.number)
    
撲克牌(color='♠', number='A')
♠
A
	#表示圓
from collections import namedtuple
card = namedtuple('圓','x y r')

#雙端隊列,deque()
	隊列,先進先出(FIFO)
    堆棧,先進後出
import queue
q = queue.Queue()
q.put('first')		#先進
q.put('second')
q.put('third')
print(q)			#<queue.Queue object at 0x0000020F9FAFA908>
print(q.get())		#first
print(q.get())		#second
print(q.get())		#third
print(q.get())		#若是隊列中的值取完了,程序會在原地等待,知道從隊列中拿到值才中止

	雙端隊列
from collections import deque
q = deque(['a','b',1,2])
q.append(3)
q.appendleft('A')
print(q.pop())		#3
print(q.popleft())	#A

	#雙端隊列,能夠根據索引,在任意位置插入值,而隊列不支持在任意位置插值,只能在首尾插值(不能插隊)
from collections import deque
q = deque(['a','b',1,2])
q.insert(3,'哈哈哈')			
print(q.pop())		#2
print(q.pop())		#哈哈哈
print(q.pop())		#1
print(q.pop())		#b
print(q.pop())		#a

#有序字典,ordereddict()
normal_d = dict([('a',1),('b',2),('c',3)])
print(normal_d)

from collections import OrderedDict
order_d = OrderedDict([('a',1),('b',2),('c',3)])
print(order_d)
order_d = OrderedDict([])
order_d['x'] = 1
order_d['y'] = 2
order_d['z'] = 3
print(order_d)

{'a': 1, 'b': 2, 'c': 3}						#無順序
OrderedDict([('a', 1), ('b', 2), ('c', 3)])		#有順序
OrderedDict([('x', 1), ('y', 2), ('z', 3)])		#有順序

#默認值字典,defaultdict()
	普通字典
values = [11,22,33,44,55,66,77,88,99]
my_dict = {}
for value in values:
    if value > 66:
        if 'k1' in my_dict.keys():
            my_dict['k1'].append(value)
        else:
            my_dict['k1'] = [value]
    else:
        if 'k2' in my_dict.keys():
            my_dict['k2'].append(value)
        else:
            my_dict['k2'] = [value]
print(my_dict)		#{'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99]}

	默認值字典
from collections import defaultdict
values = [11,22,33,44,55,66,77,88,99]
my_dict = defaultdict(list)	#在該字典中新建key,對應的value默認值就是列表
# print(my_dict)			#defaultdict(<class 'list'>, {})
for value in values:
    if value > 66:
        my_dict['k1'].append(value)
    else:
        my_dict['k2'].append(value)
print(my_dict)		#{'k2': [11, 22, 33, 44, 55, 66], 'k1': [77, 88, 99]}

	普通字典
s = 'sfregersggggggrvsdesdfrrrrrr'
d = {}
for i in s:
    if i in d.keys():
        d[i]+= 1
    else:
        d[i] = 1
print(d)

from collections import Counter
s = 'sfregersggggggrvsdesdfrrrrrr'
res = Counter(s)
print(res)			#Counter({'r': 9, 'g': 7, 's': 4, 'e': 3, 'f': 2, 'd': 2, 'v': 1})

經常使用模塊 OS

#py文件名應該避免跟已有的模塊名相同,防止導入衝突
#OS模塊是跟操做系統打交道的模塊,使用該模塊可使APP跨平臺使用

#目錄列表
import os
print(os.listdir(r'E:\python_test\ATM'))		#['bin', 'conf', 'core', 'db', 'lib', 'log', 'Readme']

import os
#當前文件所在當前目錄
BASE_DIR = os.path.dirname(__file__)
#根據獲取的當前目錄,拼接處指定目錄
MOVE_DIR = os.path.join(BASE_DIR,'老師們的做品')
#獲取指定目錄下的文件名,結果是列表
movie_list = os.listdir(MOVE_DIR)
#計算列表內的元素的個數,也就是指定目錄下的文件數
file_num = len(movie_list)
while True:
    #打印開頭用戶能夠參考的信息
    for i,j in enumerate(movie_list,1):
        print(i,j)
    choise = input('請輸入想看的資源序號>>>: ').strip()
    #判斷用戶輸入是否爲純數字
    if choise.isdigit():
        choise = int(choise)
        #判斷用戶輸入數字是否有意義
        if choise in range(1,file_num+1):
            #列表索引取值,獲得文件名
            target_file = movie_list[choise-1]
            target_path = os.path.join(MOVE_DIR,target_file)
            print(target_path)
            with open(target_path,mode='r',encoding='utf-8') as f:	#不能使用r''
                print(f.read())
                break
        else:
            print('輸入數字無效,請從新輸入,數字範圍爲>>>: 1-%s'%file_num)
    else:
        print('輸入無效,請輸入指定的數字序號')
        
#mkdir(),建立單級目錄
import os
os.mkdir('test目錄')		#與當前的python文件同級

#makedirs(),建立多級目錄
import os
os.makedirs('T1/T2')	 #與當前的python文件同級

#rmdir(),removedirs(),刪除單級空目錄
import os
os.rmdir(r'E:\python_test\test')
os.removedirs(r'E:\python_test\test目錄\testdir')

#刪除多級目錄,要刪除的目錄下不能有文件(目錄不爲空就報錯)
import os
os.removedirs(r'E:\python_test\T1\T2')

#exists(),判斷文件或目錄是否存在
import os
print(os.path.exists(r'E:\python_test\test目錄'))		#True
print(os.path.exists(r'E:\python_test\a.py'))		#True

#isfile(),判斷文件是否存在
import os
print(os.path.isfile(r'E:\python_test\老師們的做品'))		#False,目錄只返回True
print(os.path.isfile(r'E:\python_test\a.py'))		#True

#remove(),刪除一個文件
import os
os.remove(r'E:\python_test\m2.py')

#重命名目錄/文件
import os
os.rename(r'E:\python_test\a.py',r'E:\python_test\aaa.py')		#重命名文件
os.rename(r'E:\python_test\老師們的做品',r'E:\python_test\老師們的做品哈') #重命名目錄

#stat(),獲取文件/目錄的信息
import os
res = os.stat((r'E:\python_test\aaa.py'))		#獲取文件的信息
print(res)		#os.stat_result(st_mode=33206, st_ino=19140298416324717, st_dev=2122398715, st_nlink=1, st_uid=0, st_gid=0, st_size=1406, st_atime=1605492292, st_mtime=1605492292, st_ctime=1604305169)
res = os.stat((r'E:\python_test\老師們的做品哈'))	#獲取目錄的信息
print(res)		#os.stat_result(st_mode=16895, st_ino=119345390125318349, st_dev=2122398715, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1605492215, st_mtime=1605433594, st_ctime=1605255301)

#getcwd(),查看當前文件的工做目錄
import os
print(os.getcwd())		#E:\python_test

#chdir(),改變當前文件的工做目錄,至關於shell下的cd
import os
print(os.getcwd())		#E:\python_test
os.chdir(r'E:\python_test\老師們的做品哈')
print(os.getcwd())		#E:\python_test\老師們的做品哈

#system(),運行shell命令
import os
os.system('mkdir TT')

#popen(),運行shell命令,獲取執行結果
import os
os.popen('mkdir T').read()

#getsize(),獲取文件大小
import os
res = os.path.getsize(r'E:\python_test\老師們的做品哈\小澤老師')
print(res)					#7,字節
with open(r'E:\python_test\老師們的做品哈\小澤老師',mode='r',encoding='utf-8') as f:
    print(len(f.read()))	#5,字符

sys模塊

#sys模塊,是跟python解釋器打交道的模塊

#append(),將某個目錄添加到系統的環境變量中
import sys
sys.path.append(r'E:\python_test\老師們的做品哈')

#platform,查看當前的操做系統
import sys
print(sys.platform)		#win32

#version,查看python解釋器的版本
import sys
print(sys.version)		

#argv[n],獲取終端的命令行的參數
import sys
username = sys.argv[1]
password = sys.argv[2]
if username == 'syy' and password == '123':
    print('當前代碼')
else:
    print('用戶名或密碼錯誤')
E:\python_test>python E:\python_test\aaa.py syy 123

#實例
import sys
if len(sys.argv) != 3:
    print('請輸入用戶名和密碼')
else:
    username = sys.argv[1]
    password = sys.argv[2]
    if username == 'syy' and password == '123':
        print('當前代碼')
    else:
        print('用戶名或密碼錯誤')

time模塊

#time的三種表現形式
	1.時間戳
    2.格式化時間(給人看的)
    3.結構化時間
    
	#時間戳
import time
print(time.time())							#1605249911.3957567

	#格式化時間
print(time.strftime('%Y-%m-%d'))			#2020-11-13
print(time.strftime('%Y-%m-%d %H:%M:%S'))	#2020-11-13 14:47:11
print(time.strftime('%Y-%m-%d %X'))			#等價,2020-11-13 14:48:58
print(time.strftime('%m/%d %H:%M:%S')) 		#拼接,11/13 14:48:05
    
    #結構化時間
print(time.localtime())		#time.struct_time(tm_year=2020, tm_mon=11, tm_mday=13, tm_hour=14, tm_min=50, tm_sec=50, tm_wday=4, tm_yday=318, tm_isdst=0)

#三種時間的轉化
	#時間戳轉結構化時間
import time
print(time.localtime(1605249911.3957567))	#time.struct_time(tm_year=2020, tm_mon=11, tm_mday=13, tm_hour=6, tm_min=45, tm_sec=11, tm_wday=4, tm_yday=318, tm_isdst=0)
import time
print(time.gmtime(1605249911.3957567))
    #結構化時間轉時間戳
import time
res = time.localtime(time.time())
print(time.mktime(res))		#1605250876.0
print(time.time())			#1605250876.6250167

	#格式化時間轉結構化時間
import time
res = time.strftime('%Y-%m-%d %H:%M:%S')
print(time.strptime(res,'%Y-%m-%d %H:%M:%S'))
    #結構化時間轉格式化時間
import time
print(time.strftime('%Y-%m-%d %H:%M:%S',time.localtime()))	#2020-11-13 15:10:12
    
#time.sleep()
import time
print('倒計時: 3...')
print(time.sleep(1))
print('倒計時: 2..')
print(time.sleep(1))
print('倒計時: 1.')
print(time.sleep(1))
print('倒計時: 0')
    
倒計時: 3...
None
倒計時: 2..
None
倒計時: 1.
None
倒計時: 0

datatime模塊

#datatime模塊
import datetime
print(datetime.date.today())		#2020-11-13(年月日)
print(datetime.datetime.today())	#2020-11-13 15:18:02.062366(年月日時分秒)
print(res1.year)					#2020
print(res1.month)					#11
print(res1.day)						#13
print(res1.weekday())				#4(用0-6表示)
print(res1.isocalendar())			#(2020, 46, 5)(星期用1-7表示,7表示週日)

#時間能夠相加減
	#日期對象 = 日期對象 +/- timedelta對象
import datetime
corrent_time = datetime.date.today()
timetel_t = datetime.timedelta(days=3)
print(corrent_time+timetel_t)		#2020-11-16
    #timedelta對象 = 日期對象 +/- 日期對象
    
#UTC時間
import datetime
dt_today = datetime.datetime.today()
dt_now = datetime.datetime.now()
dt_utcnow = datetime.datetime.utcnow()
print(dt_today,dt_now,dt_utcnow)
2020-11-13 15:34:25.711797 
        2020-11-13 15:34:25.711797 
                2020-11-13 07:34:25.711797

json模塊

#序列化
	序列:		字符串
    序列化:	其餘數據類型轉換成字符串的過程
    反序列化:	字符串轉換成其餘數據類型
    
#爲何要使用序列化
數據有指定的數據類型,轉換成字符串(序列化),才能str.encoding轉化爲二進制數據(基於網絡傳輸的數據必須是二進制數據),進而寫入文件

#json模塊的優勢
	全部編程語言均可以使用json格式,也就是說,json代碼能夠跨語言、跨平臺使用
    
#json模塊的缺點:
	支持的數據類型少(json只能夠轉字符串、列表、字典,不能轉對象、索引、函數等)

#json可以支持的python的數據類型,python中其餘的數據類型json都不支持
import json
json.JSONEncoder
    +-------------------+---------------+
    | Python            | JSON          |
    +===================+===============+
    | dict              | object        |對象(字符串)
    +-------------------+---------------+
    | list, tuple       | array         |數組(字符串)
    +-------------------+---------------+
    | str               | string        |字符串
    +-------------------+---------------+
    | int, float        | number        |數值
    +-------------------+---------------+
    | True              | true          |
    +-------------------+---------------+
    | False             | false         |
    +-------------------+---------------+
    | None              | null          |
    +-------------------+---------------+
    
  
#dumps()序列化,將其餘的數據類型轉換成json格式的字符串
#loads()反序列化,將json格式的字符串轉換成其餘的數據類型
import json
d = {"name":"syy"}
print(d)				#{'name': 'syy'},只有json格式的數據打印出來是雙引號
res = json.dumps(d)
print(res)				#{"name": "syy"},等效於'{"name": "syy"}'
print(type(res))		#<class 'str'>
res = json.loads(res)
print(res)				#{'name': 'syy'}
print(type(res))		#<class 'dict'>

#dump(),load()
import json
d = {"name":"syy"}
with open(r'userinfo','w',encoding='utf-8') as f:
    json.dump(d,f)		#轉換成字符串,而且自動寫入
with open(r'userinfo','r',encoding='utf-8') as f:
    res = json.load(f)
    print(res,type(res))	#{'name': 'syy'} <class 'dict'> 

#反序列化中的問題,以及解決方法
import json
d = {"name":"syy"}
with open(r'userinfo','w',encoding='utf-8') as f:
    json.dump(d,f)
    json.dump(d,f)
with open(r'userinfo','r',encoding='utf-8') as f:
    res = json.load(f)		#不能屢次反序列化
    print(res,type(res))	#json.decoder.JSONDecodeError:

	#解決方法
import json
d = {"name":"syy"}
with open(r'userinfo','w',encoding='utf-8') as f:
    json_str = json.dumps(d)
    json_str2 = json.dumps(d)
    f.write('%s\n'%json_str)
    f.write('%s\n'%json_str2)
with open(r'userinfo','r',encoding='utf-8') as f:
    for line in f:
        res = json.loads(line)
        print(res,type(res)) 

#將元組轉換成數組
import json
t = (1,2,3)
res = json.dumps(t)
print(res,type(res))   		#[1, 2, 3] <class 'str'>
       
#中文轉json的時候的轉碼問題
import json
d = {'name':'豬堅強'}
print(json.dumps((d)))						#{"name": "\u732a\u575a\u5f3a"}
print(json.dumps(d,ensure_ascii=False))		#{"name": "豬堅強"}

pickle模塊

#pickle模塊
    python全部的數據類型都支持pickle模塊(包括對象、索引、函數)
    
#pickle模塊
	只能本身跟本身玩,不支持跨語言傳輸
    只有python才能使用pickle模塊

#dumps(),loads()
import pickle
d = {'name':'syy'}
res = pickle.dumps(d)
print(res)		#b'\x80\x03}q\x00X\x04\x00\x00‘,將對象直接轉換成二進制
res = pickle.loads(res)
print(res,type(res))		#{'name': 'syy'} <class 'dict'>

#dump(),load()
	#使用pickle操做文件的時候,文件的打開模式必須是b模式
import pickle
d = {'name':'syy'}
with open(r'userinfo','wb') as f:
    pickle.dump(d,f)
with open(r'userinfo','rb') as f:	
    res = pickle.load(f)
    print(res,type(res))		#{'name': 'syy'} <class 'dict'>

random模塊

#隨機數
import random
print(random.randint(1,6))	#1,包括首尾

import random
print(random.random())		#0.5979006446755478,取0-1之間的小數

import random
print(random.choice([1,2,3,4,5,6]))		#2,從列表中隨機取值

import random
res = [1,2,3,4,5,6]
random.shuffle(res)
print(res)			#[2, 1, 3, 6, 5, 4],打亂順序

#生成隨機驗證碼
	驗證碼由大寫字母、小寫字母、數字組成
import random
def get_code(n):
    code = ''
    for i in range(n):
        upper_str = chr(random.randint(65,90))
        lower_str = chr(random.randint(97,122))
        random_int = str(random.randint(0,9))
        code +=random.choice([upper_str,lower_str,random_int])
    return code
res = get_code(5)
print(res)

#驗證碼忽略大小寫
	使用upper()、lower()統一轉換成大寫或者小寫
s = 'rigllllllllllllf'
res = s.upper()
print(res)
res = s.lower()
print(res)

logging模塊

#日誌
	日誌本質上是就是一個文本文件,咱們能夠直接寫入,可是太麻煩,因此使用logging模塊封裝了日誌的編輯

#logging模塊也叫日誌模塊
	記錄程序的輸入與輸出
    
#日誌分爲5個等級
import logging
file_handler = logging.FileHandler(filename='x1.log', mode='a', encoding='utf-8',)
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    handlers=[file_handler,],
    level=logging.ERROR
)
logging.error('你好')
logging.debug('debug日誌')		#10
logging.info('info日誌')			#20
logging.warning('warning日誌')	#30
logging.error('error日誌')		#40
logging.critical('critical日誌')	#50

2020-11-17 15:37:47 PM - root - ERROR -aaa:  你好
2020-11-17 15:37:47 PM - root - DEBUG -aaa:  debug日誌
2020-11-17 15:37:47 PM - root - INFO -aaa:  info日誌
2020-11-17 15:37:47 PM - root - WARNING -aaa:  warning日誌
2020-11-17 15:37:47 PM - root - ERROR -aaa:  error日誌
2020-11-17 15:37:47 PM - root - CRITICAL -aaa:  critical日誌

#問題
	1.亂碼
    2.日誌格式
    3.如何既打印到終端,又寫入到文件
    
#學習logging模塊須要瞭解的幾個核心的對象(角色)
	1.logger對象:負責產生日誌
    2.filter對象:過濾日誌
    3.handler對象:控制日誌輸出的位置(文件/終端)
    4.formmater對象:規定日誌內容的格式

#參數
logging.basicConfig()函數中可經過具體參數來更改logging模塊默認行爲,可用參數有:
filename:用指定的文件名建立FiledHandler,這樣日誌會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值爲「a」還可指定爲「w」。
format:指定handler使用的日誌顯示格式。
datefmt:指定日期時間格式。
level:設置rootlogger(後邊會講解具體概念)的日誌級別
stream:用指定的stream建立StreamHandler。能夠指定輸出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默認爲sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。
format參數中可能用到的格式化串:
%(name)s Logger的名字
%(levelno)s 數字形式的日誌級別
%(levelname)s 文本形式的日誌級別
%(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有
%(filename)s 調用日誌輸出函數的模塊的文件名
%(module)s 調用日誌輸出函數的模塊名
%(funcName)s 調用日誌輸出函數的函數名
%(lineno)d 調用日誌輸出函數的語句所在的代碼行
%(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示
%(relativeCreated)d 輸出日誌信息時的,自Logger建立以 來的毫秒數
%(asctime)s 字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒
%(thread)d 線程ID。可能沒有
%(threadName)s 線程名。可能沒有
%(process)d 進程ID。可能沒有
%(message)s用戶輸出的消息

#logger對象配置
import logging
logger = logging.getLogger()
# 建立一個handler,用於寫入日誌文件
fh = logging.FileHandler('test.log',encoding='utf-8') 
# 再建立一個handler,用於輸出到控制檯 
ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setLevel(logging.DEBUG)fh.setFormatter(formatter) ch.setFormatter(formatter) 
logger.addHandler(fh) 
#logger對象能夠添加多個fh和ch對象 
logger.addHandler(ch) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')

#日誌切割
import time
import logging
from logging import handlers
sh = logging.StreamHandler()
rh = handlers.RotatingFileHandler('myapp.log', maxBytes=1024,backupCount=5)
fh = handlers.TimedRotatingFileHandler(filename='x2.log', when='s', interval=5, encoding='utf-8')
logging.basicConfig(
    format='%(asctime)s - %(name)s - %(levelname)s -%(module)s:  %(message)s',
    datefmt='%Y-%m-%d %H:%M:%S %p',
    handlers=[fh,sh,rh],
    level=logging.ERROR
)
for i in range(1,100000):
    time.sleep(1)
    logging.error('KeyboardInterrupt error %s'%str(i))

subprocess模塊

#sub		子
#process	進程

#
import subprocess
while True:
    cmd = input('please input your command>>>: ').strip()
    obj = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
    print('stdout',obj.stdout.read().decode('gbk'))		#正確命令的返回結果
    print('stderr',obj.stderr.read().decode('gbk'))		#錯誤命令返回的提示信息

#過程分析
	1.用戶經過網絡,鏈接電腦
    2.用戶輸入相應的命令,基於網絡發送給這臺電腦上的某個程序
    3.獲取用戶輸入的命令,python解釋器經過subprocess模塊執行用戶的命令
    4.將執行結果再基於網絡發送給用戶,這樣就實現了用戶的遠程操做

#模塊的三種來源
	1.內置的
    2.第三方的
    3.自定義的
    
#模塊的四種表現形式
	1.py文件
    2.共享庫
    3.文件夾/包(一系列模塊的結合體)
    4.C++編譯鏈接到python內置的 
   
#使用import導入模塊
	1.產生一個執行文件的名稱空間
    2.建立模塊文件的名稱空間
    3.執行模塊文件中的代碼,將產生的名字放入模塊文件的名稱空間中
    4.在執行文件的名稱空間中,建立一個指向模塊文件名稱空間的名字

#模塊與包
	#能夠站在兩個角度來分析不一樣的問題
    1.模塊的開發者
    2.模塊的使用者
    
#包
	包是一系列模塊文件的結合體,他的表現形式就是一個文件夾
    該文件夾內部一般會有一個__init__.py文件
    包的本質仍是一個模塊
    
#導入包
	1.產生一個執行文件的名稱空間
    2.建立包下面的__init__.py文件的名稱空間
    3.執行包下面的__init__.py文件中的代碼,將產生的名字放入包下面的__init__.py文件的名稱空間中
    4.在執行文件中,建立一個指向包下面的__init__.py文件的名稱空間的名字
    
#導入包的時候,.號的左邊永遠是包(文件夾)
#看成爲包的設計者來講
	1.當模塊的功能特別多的狀況下,應該分文件管理,也就是作成包
    2.每一個模塊之間爲了不後期模塊更名的問題,可使用相對導入,由於包裏面的文件都應該是被導入的模塊
# import m1
# import m2
# import m3
# import m1.f1				#不支持,import只能導入模塊

# import bao.m1
# import bao.m2
# import bao.m3
# import bao.bao2.m4		#支持

# from bao import m1
# from bao import m2
# from bao import m3
# from bao.bao2 import m4	#支持
# from bao.m1 import f1		#支持

# import m4                 #不報錯
import bao2.m4              #報錯
# from bao.bao2 import m4   #不報錯
# import .m4                #報錯
# from .m4 import m4        #報錯

#站在包的開發者來講,若是使用絕對路徑來管理本身的模塊,那麼他只須要以包爲基準,依次導入模塊
#站在包的使用者來講,必須將包所在的那個文件夾路徑添加到system.path中

#python2中,若是要導入包,包下面必需要有__init__.py文件
#python3中,若是要導入包,包下面沒有__init__.py文件也不會報錯
	#當刪除代碼中沒必要要的文件的時候,千萬不要隨意刪除__init__.py文件

configparse模塊

 

hashlib模塊

#算法模塊、加密模塊	
	該模塊只能加密,不能解密
    相同的加密數據,獲得的密文必定相同,密文相同,加密數據必定相同
    不一樣的加密方法,加密過程相同
    密文的長度越長,對應的算法越複雜,可是時間消耗越長,佔用空間越大,一般使用md5加密算法(32位)
    要加密的數據能夠分屢次傳入
 
#md5()
import hashlib
md = hashlib.md5()                      #生成一個造密文的對象
md.update('hello'.encode('utf-8'))      #向對象中傳明文數據
# md.update(b'hello')                   #等效
print(md.hexdigest())					#5d41402abc4b2a76b9719d911017c592

#sha3_256()      
import hashlib
md = hashlib.sha3_256()                    
md.update('hello'.encode('utf-8'))     
# md.update(b'hello')                   
print(md.hexdigest())	#3338be694f50c5f338814986cdf0686453a888b84f424d792a

#加密對象的屢次傳入
import hashlib
md = hashlib.md5()
md.update('he'.encode('utf-8'))
md.update('ll'.encode('utf-8'))
md.update('o'.encode('utf-8'))
print(md.hexdigest())		#5d41402abc4b2a76b9719d911017c592

#hashlib模塊的應用場景
	1.密碼的密文傳輸
	2.校驗文件的內容是否一致
    
#加鹽處理、動態加鹽
import hashlib
md = hashlib.md5()
md.update('加鹽'.encode('utf-8'))
md.update('hello'.encode('utf-8'))
print(md.hexdigest())		#7e17f9d744b7f40b93c22fa9da785d40

import hashlib
md = hashlib.md5()
md.update('加鹽hello'.encode('utf-8'))
print(md.hexdigest())		#7e17f9d744b7f40b93c22fa9da785d40

#實例
import hashlib
def get_md5(data):
    md = hashlib.md5()
    md.update('加鹽'.encode('utf-8'))
    md.update(data.encode('utf-8'))
    return md.hexdigest()
password = input('請輸入你的密碼>>>: ').strip()
res = get_md5(password)
print('密碼密文爲:加鹽%s',%res)

openpyxl模塊

#操做Excel表格的模塊
	Excel文件在03版本以前,後綴名叫xls
    Excel文件在03版本以後,後綴名叫xlsx

#xlwd模塊
	寫Excel
#xlrt模塊
	讀Excel
    
#xlwd模塊、xlrt模塊,既支持03版本以前的Excel文件,也支持03版本以後的文件
#openyxl模塊,只支持03版本以後的文件

#openpyxl模塊
from openpyxl import Workbook
wb = Workbook()         #先生成一個工做蒲
wb1 = wb.create_sheet('index0',0)        #指定sheet名,初始化sheet位置
wb2 = wb.create_sheet('index1',1)
wb3 = wb.create_sheet('index2',2)

wb1.append(['username','age','hobby'])      #添加表頭
wb1.append(['syy',18,'study'])              #添加數據
wb1['A3'] = 666         #在指定的sheet中寫入內容
wb1['A4'] = 777
wb2['G6'] = 888
wb3.cell(row=6,column=3,value=999)
wb1['A5'] = '=sum(A3:A4)'       #求和

wb1.title = 'login'     #修改sheet名
wb.save('test.xlsx')    #指定文件名

copy模塊

#淺拷貝
	#淺拷貝中不可變數據類型指向的是同一個
    #淺拷貝中可變數據類型拷貝指向的仍是原來的拷貝對象,而深拷貝指向的是新的
    
#深拷貝
	#深拷貝中,全部的id指向的都是對應的同一個值
    #深淺拷貝的本質在於新的變量名指向的值,的指向是原來的內存地址仍是原來的值

#鏈式變量
l = [1,2,[1,2]]
l1 = l
print(id(l),id(l1))		#2422474796744 2422474796744
l[0] = 222
print(l,l1)				#[222, 2, [1, 2]] [222, 2, [1, 2]]

#copy模塊
import copy
l = [1,2,[1,2]]
l1 = copy.copy(l)
print(id(l),id(l1))		#1742143678728 1742143677768
l[0] = 222				#這部分是深拷貝
print(l,l1)				#[222, 2, [1, 2]] [1, 2, [1, 2]]
l[2].append(666)		#這部分是淺拷貝
print(l,l1)				#[1, 2, [1, 2, 666]] [1, 2, [1, 2, 666]]

#深拷貝
import copy
l = [1,2,[1,2]]
l1 = copy.deepcopy(l)
print(id(l),id(l1))
l[2].append(666)
print(l,l1)

2493117098248 2493117097288
[1, 2, [1, 2, 666]] [1, 2, [1, 2]]
相關文章
相關標籤/搜索