日誌就是記錄一些信息,方便查詢或者輔助開發node
記錄文件,顯示屏幕python
屏幕輸出數據庫
import logging logging.debug('調試模式') #默認只輸出warning以上信息, logging.info('正常運行') logging.warning('警告') logging.error('錯誤') logging.critical('系統崩潰') WARNING:root:警告 ERROR:root:錯誤 CRITICAL:root:系統崩潰
寫入文件json
import logging logging.basicConfig( level=logging.DEBUG, #level=10, # 顯示的級別 format='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s', # 顯示格式 datefmt='%Y %m %d', # 日期 filename='a.log', # 默認是a模式, 就是使用的gbk 編碼。 # filemode='w' #通常只用追加寫入,不用寫入 所以不用改寫模式。 ) logging.debug('調試模式') # 等於10 logging.info('正常運行') # 等於20 logging.warning('警告') # 等於30 logging.error('錯誤') # 等於40 logging.critical('系統崩潰') # 等於50
import logging # 建立logging對象 log = logging.getLogger() # 建立文件對象 f1 = logging.FileHandler('file1.log', encoding='utf-8') f2 = logging.FileHandler('file2.log', encoding='utf-8') #建立屏幕對象 sh = logging.StreamHandler() # 日誌格式設置 format1 = logging.Formatter( fmt='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s', # 顯示格式 datefmt='%Y-%m-%d %H:%M:%S',) #顯示時間設置 format2 = logging.Formatter( fmt='%(asctime)s %(filename)s %(levelname)s ', # 顯示格式 datefmt='%Y-%m-%d %H:%M:%S',) #顯示時間設置 format3 = logging.Formatter( fmt='%(asctime)s %(filename)s [line:%(lineno)d] %(levelname)s %(message)s', # 顯示格式 datefmt='%Y-%m-%d %H:%M:%S',) #顯示時間設置 # 給建立的輸出對象綁定格式 f1.setFormatter(format1) f2.setFormatter(format2) sh.setFormatter(format3) #給log對象添加輸出對象 log.addHandler(f1) log.addHandler(f2) log.addHandler(sh) #設置級別 log.setLevel(20) sh.setLevel(30) f1.setLevel(30) f2.setLevel(40) logging.debug('調試模式') logging.info('正常運行') logging.warning('警告') logging.error('錯誤') logging.critical('系統崩潰')
經過導入文件(字典的方式)寫日誌,Django網絡
import os import logging.config # 定義日誌的輸出的格式 standard_format = '[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]' \ '[%(levelname)s][%(message)s]' # 其中name爲getlogger指定的名字 simple_format = '[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s' id_simple_format = '[%(levelname)s][%(asctime)s] %(message)s' # 找到當前目錄絕對路徑 __file__ logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目錄的絕對路徑 logfile_name = '高配版.log' # log文件名 # # 若是不存在定義的日誌目錄就建立一個 # if not os.path.isdir(logfile_dir): # os.mkdir(logfile_dir) # log文件的全路徑 logfile_path = os.path.join(logfile_dir, logfile_name) # log配置字典 # 第一層鍵值對的鍵固定的關鍵字不能改變。 LOGGING_DIC = { 'version': 1, # 版本 'disable_existing-loggers': False, # 禁用現有的log日誌 'formatters': { # 定義三種不一樣的日誌格式 'standard': { # 格式1 'format': standard_format }, 'simple': { # 格式2 'format': simple_format }, 'id_simple_format': { # 格式3 'format': id_simple_format } }, 'filters': {}, # 過濾 'handlers': { 'console': { # 打印到終端的日誌 'level': 'DEBUG', # 日誌級別 'class': 'logging.StreamHandler', # 類:打印到屏幕 'formatter': 'simple' # 日誌的格式 }, 'default': { 'level': 'DEBUG', 'class': 'logging.handlers.RotatingFileHandler', # 保存到文件 'formatter': 'standard', # 日誌的格式 'filename': logfile_path, # 日誌文件的絕對路徑 'maxBytes': 1024*1024*5, # 日誌大小5M,以bytes 'backupCount': 5, # 最多隻有5個文件 'encoding': 'utf-8', }, }, 'loggers': { '': { 'handlers': ['default', 'console'], # 這裏把上面定義的兩個handler都加上,即log數據既寫入文件又打印到屏幕 'level': 'DEBUG', 'propagate': True, # 向上(更高level的logger)傳遞 }, }, } logging.config.dictConfig(LOGGING_DIC) # 導入上面定義的logging配置 # # logging.config # 將你寫好的logging 字典 在導入logging.config後,傳到logging模塊中 logger = logging.getLogger() # 生成一個log實例 經過字典本身設置的個性化的log對象 logger.info('正常運行狀態') # 記錄該文件的運行狀態
1.加密的類型必須是strapp
2.不管這個str多長,加密以後都是轉化成等長度的數字.框架
3.不管在任何機器上,函數
不一樣的字符串加密後必定不一樣編碼
import hashlib ret = hashlib.md5() #定義一個ret的對象 ret.update('wk'.encode('utf-8')) #將字符串'wk'轉爲bytes 加密 print(ret.hexdigest()) #查看轉換後的密文 5d2bf8e6622cb88ca16a745dcf8153a0
a.普通的md5加密加密
import hashlib def encryption(passwd): #加密函數 ret = hashlib.md5() ret.update(passwd.encode('utf-8')) return ret.hexdigest() def register(): user = input('>>>') passwd = input('>>>') passwd = encryption(passwd) with open('ku', encoding='utf-8', mode='a') as f1: f1.write('{}|{}'.format(user, passwd)) register()
用戶註冊完登陸時,將登錄的密碼再次加密而後與存儲的進行對比
b,加鹽
import hashlib def encryption(passwd): ret = hashlib.md5('加鹽'.encode('utf-8')) #在別人設置的密碼前再加一串固定的字符,使md5不容易破譯,可是若是別人知道你的鹽是什麼仍是能夠破譯 ret.update(passwd.encode('utf-8')) return ret.hexdigest() def register(): user = input('>>>') passwd = input('>>>') passwd = encryption(passwd) with open('ku', encoding='utf-8', mode='a') as f1: f1.write('{}|{}'.format(user, passwd)) register()
c.動態加鹽
import hashlib def encryption(user, passwd): ret = hashlib.md5(user[::2].encode('utf-8')) #加的鹽爲用戶名字符的奇數字符 ret.update(passwd.encode('utf-8')) return ret.hexdigest() def register(): user = input('>>>') passwd = input('>>>') passwd = encryption(user,passwd) with open('ku', encoding='utf-8', mode='a') as f1: f1.write('{}|{}'.format(user, passwd)) register()
import hashlib def encryption(user, passwd): ret = hashlib.sha1(user[::2].encode('utf-8')) #與md5用法同樣,把md5改成sha1
ret.update(passwd.encode('utf-8')) return ret.hexdigest() def register(): user = input('>>>') passwd = input('>>>') passwd = encryption(user,passwd) with open('ku', encoding='utf-8', mode='a') as f1: f1.write('{}|{}'.format(user, passwd)) register()
哈希的加密方法有不少,尾數越高,加密方法越複雜,效率越低
校驗文件就是把文件的內容生成MD5值,把MD5值對比校驗
校驗文件
import hashlib def file_hashlib(file): ret = hashlib.md5() with open(file,mode='rb') as f1: ret.update(f1) return ret.hexdigest() file_hashlib('文件')
校驗能夠累加
import hashlib s1 = '蹦沙卡拉卡' #一個字符串一次性讀取和分次讀取其生成的MD5值同樣(必須是相同字符串) ret = hashlib.md5() ret.update(s1.encode('utf-8')) print(ret.hexdigest()) ret = hashlib.md5() ret.update('蹦'.encode('utf-8')) ret.update('沙'.encode('utf-8')) ret.update('卡'.encode('utf-8')) ret.update('拉'.encode('utf-8')) ret.update('卡'.encode('utf-8')) print(ret.hexdigest()) 5f46742e84df43713d132852859aa3bb 5f46742e84df43713d132852859aa3bb
對於大文件每次讀取一行,按行累加校驗
import hashlib def file_hashlib(file): ret = hashlib.md5() with open(file,mode='rb') as f1: for i in f1: # 循環每行讀取 ret.update(i) return ret.hexdigest() file_hashlib('文件')
異常發生後下邊的代碼就再也不執行了
name #單有一個變量名運行 Traceback (most recent call last): #報錯 File "F:/python24期/python/123.py", line 1, in <module> name NameError: name 'name' is not defined #報錯 NameError
try--except: 嘗試着運行try裏面的代碼,出現錯誤,按照錯誤類型去尋找相應的except,找到執行except裏的代碼,而後程序繼續運轉.
try: #代碼能夠運行而且不報錯 print(555) name #出現錯誤即跳轉到except,不在往下執行 print(666) except NameError: #定義錯誤類型 print('name name is not defined') print(777) 555 #錯輸出結果可見,try裏的 錯誤代碼下的代碼不執行, 遇到錯誤後看except是否有指定錯誤,若是有,執行except裏的代碼, name name is not defined 777
上述方法只能鎖定一個錯誤,若是錯誤沒有在except裏,則程序還會報錯
try: print(555) l1 = [1, 2, 3] print(l1[10]) #打印列表的第10個參數,可是列表裏只有2個參數 此時報IndexError錯誤 print(666) except NameError: #except裏沒有定義IndexError錯誤,所以程序執行到print(l1[10])仍是會報錯並終止程序 print('name name is not defined') print(777) Traceback (most recent call last): 555 File "F:/python24期/python/123.py", line 4, in <module> print(l1[10]) IndexError: list index out of range
try: print(555) name l1 = [1, 2, 3] print(l1[10]) print(666) dic = {'name': 'alex'} print(dic['age']) except NameError: #定義多個except,可是仍是try裏的代碼,遇到錯誤即中止往下執行 print('name name is not defined') except IndexError: print('索引超出範圍....') except KeyError: print('沒有此key...') print(777) 555 name name is not defined 777
若是你對錯誤緣由不關心,只是想不讓其報錯,那麼程序中你就用萬能處理.
若是你對錯誤緣由須要進行不一樣分流或者程序處理,那麼就須要多分支.
try: print(555) name l1 = [1, 2, 3] print(l1[10]) print(666) dic = {'name': 'alex'} print(dic['age']) except Exception as e: #Exception能夠接收全部錯誤, as e 把錯誤結果賦值給e print(e) print(777) 555 name 'name' is not defined 777
try: print(555) name l1 = [1, 2, 3] print(l1[10]) print(666) dic = {'name': 'alex'} print(dic['age']) except NameError: #定義多個except, print('name name is not defined') except IndexError: print('索引超出範圍....') except KeyError: print('沒有此key...') except Exception as e: #前邊分流接收,最後以Exception 收尾 print(e) print(777)
try: print(555) name except NameError: print('name name is not defined') else: #若是try裏報錯而且執行except,則代碼往下走不執行else print(999) print(777) 555 #輸出結果沒有執行else裏的代碼 name name is not defined 777
try: print(555) name = 123 except NameError: #若是try裏的代碼沒有報錯,而且沒有執行except,則執行else裏的代碼 print('name name is not defined') else: print(999) print(777) 555 999 #此處執行了else裏的代碼 777
finaly 無論對與錯都執行finally 可是代碼不會繼續往下走,
try: name = 123 finally: print(777) try: li = [1,2,3] print(li[10]) finally: print(666) print(888) #print(888)沒有執行 Traceback (most recent call last): 777 #無論對錯finally內的代碼都執行了 666 File "F:/python24期/python/123.py", line 7, in <module> print(li[10]) IndexError: list index out of range
常做用於關閉文件,關閉鏈接,關閉數據庫等等
f1 = open('a.log', encoding='utf-8') f1.read() ''' 各類對文件操做的代碼,可是可能會出錯,出錯以後,你的文件句柄沒法關閉。 ''' f1.close()
# 解決方案: try: f1 = open('a.log', encoding='gbk') f1.read() f1.write('sfdsf') ''' 各類對文件操做的代碼,可是可能會出錯,出錯以後,你的文件句柄沒法關閉。 ''' finally: print(666) f1.close()
try findally也能夠做用於函數
def aa(x): try: c = x + 1 return c finally: #finally做用於函數先執行finally再執行return print(666) print(aa(1)) 666 #先執行的findlly 2 #再執行的c=2
try: name = 123 finally: print(777) try: li = [1,2,3] print(li[10]) except Exception: pass finally: print(666) print(888) 777 666 888
python提供了大部分異常,可是不是全部,好比 大的框架的手機鏈接問題,網絡引起的代碼問題等等.
Exception 也處理不了.
class PhoneConnectionError(BaseException): #定義一個類,繼承BaseException 類 pass raise PhoneConnectionError('錯誤類型') #raise報一個指定的錯誤,此錯誤必須定義class PhoneConnectionError(BaseException):才能出現 Traceback (most recent call last): File "F:/python24期/python/123.py", line 5, in <module> raise PhoneConnectionError('錯誤類型') __main__.PhoneConnectionError: 錯誤類型 #PhoneConnectionError的錯誤
要想讓except可以找到自定義的錯誤類型,須要自定義一個錯誤類而且繼承BaseException累
class PhoneConnectionError(BaseException): #若是出現python解決不了的錯誤類型,就定義一個錯誤類,讓這個類繼承BaseException pass try: raise PhoneConnectionError('錯誤類型') except PhoneConnectionError: print('手機鏈接出現了問題') 手機鏈接出現了問題
assert 斷言 只要條件不成立就報錯
assert 1 == 2 #源碼中常常遇到 只要條件不成立,我就拋出錯誤
Traceback (most recent call last): File "F:/python24期/python/123.py", line 1, in <module> assert 1 == 2 AssertionError
獲取當前時間
import datetime now_time = datetime.datetime.now() print(now_time)
2019-01-10 19:49:42.388032
獲取3周以後和3周以前的當前時間
import datetime print(datetime.datetime.now()) print(datetime.datetime.now()+datetime.timedelta(weeks=3)) #3周以後的時間 print(datetime.datetime.now()+datetime.timedelta(weeks=-3)) #3周以前的時間 2019-01-10 19:55:01.222595 2019-01-31 19:55:01.222595 2018-12-20 19:55:01.222595
獲取其餘時間
import datetime print(datetime.datetime.now()) print(datetime.datetime.now()+datetime.timedelta(days=3)) #3天后 print(datetime.datetime.now()+datetime.timedelta(days=-3)) #3天前 print(datetime.datetime.now()+datetime.timedelta(hours=3)) #3小時後 print(datetime.datetime.now()+datetime.timedelta(hours=-3)) #3小時前 print(datetime.datetime.now()+datetime.timedelta(minutes=3)) #3分鐘後 print(datetime.datetime.now()+datetime.timedelta(minutes=-3)) #3分鐘前 print(datetime.datetime.now()+datetime.timedelta(seconds=3)) #3秒後 print(datetime.datetime.now()+datetime.timedelta(seconds=-3)) #3秒前 2019-01-10 19:59:35.137924 2019-01-13 19:59:35.137924 2019-01-07 19:59:35.137924 2019-01-10 22:59:35.137924 2019-01-10 16:59:35.137924 2019-01-10 20:02:35.137924 2019-01-10 19:56:35.137924 2019-01-10 19:59:38.137924 2019-01-10 19:59:32.137924
可直接調整到年月日時分秒
import datetime current_time = datetime.datetime.now() print(current_time.replace(year=1977)) # 直接調整到1977年 print(current_time.replace(month=1)) # 直接調整到1月份 print(current_time.replace(year=1989,month=4,day=25)) # 1989-04-25 18:49:05.898601 1977-01-10 20:03:57.756185 2019-01-10 20:03:57.756185 1989-04-25 20:03:57.756185
將時間戳轉化成時間
import datetime print(datetime.date.fromtimestamp(1232132131)) 2009-01-17
高級的 文件、文件夾、壓縮包 處理模塊
shutil.copyfileobj(fsrc, fdst[, length])
將文件內容拷貝到另外一個文件中
import shutil shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
shutil.copyfile(src, dst)
拷貝文件
shutil.copyfile('f1.log', 'f2.log') #目標文件無需存在
shutil.copymode(src, dst)
僅拷貝權限。內容、組、用戶均不變
shutil.copymode('f1.log', 'f2.log') #目標文件必須存在
shutil.copystat(src, dst)
僅拷貝狀態的信息,包括:mode bits, atime, mtime, flags
shutil.copystat('f1.log', 'f2.log') #目標文件必須存在
shutil.copy(src, dst)
拷貝文件和權限
import shutil shutil.copy('f1.log', 'f2.log')
shutil.copy2(src, dst)
拷貝文件和狀態信息
import shutil shutil.copy2('f1.log', 'f2.log')
shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
遞歸的去拷貝文件夾
import shutil shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目標目錄不能存在,注意對folder2目錄父級目錄要有可寫權限,ignore的意思是排除
shutil.rmtree(path[, ignore_errors[, onerror]])遞歸的去刪除文件
import shutil shutil.rmtree('folder1')
shutil.move(src, dst)
遞歸的去移動文件,它相似mv命令,其實就是重命名。
shutil.move('folder1', 'folder3')
shutil.make_archive(base_name, format,...)
建立壓縮包並返回文件路徑,例如:zip、tar
建立壓縮包並返回文件路徑,例如:zip、tar
#將 /data 下的文件打包放置當前程序目錄 import shutil ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data') #將 /data下的文件打包放置 /tmp/目錄 import shutil ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細:
import zipfile # 壓縮 z = zipfile.ZipFile('laxi.zip', 'w') z.write('a.log') z.write('data.data') z.close() # 解壓 z = zipfile.ZipFile('laxi.zip', 'r') z.extractall(path='.') z.close() zipfile壓縮解壓縮 import tarfile # 壓縮 >>> t=tarfile.open('/tmp/egon.tar','w') >>> t.add('/test1/a.py',arcname='a.bak') >>> t.add('/test1/b.py',arcname='b.bak') >>> t.close() # 解壓 >>> t=tarfile.open('/tmp/egon.tar','r') >>> t.extractall('/egon') >>> t.close() tarfile壓縮解壓縮
xml是實現不一樣語言或程序之間進行數據交換的協議,跟json差很少,但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代,
你們只能選擇用xml呀,至今不少傳統公司如金融行業的不少系統的接口還主要是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數據 xml文件
# 增刪改查 # 在進行操做以前,都應該進行這兩步: # import xml.etree.ElementTree as ET # tree = ET.parse('a.xml') # 造成樹形結構 # root = tree.getroot() # 獲得樹的根系 # print(root) # 循環打印: # for i in root: # print(i) # <Element 'country' at 0x00000196B51191D8> # <Element 'country' at 0x00000196B5124B88> # <Element 'country' at 0x00000196B5124D18> # 全部的增刪改查都是基於這個root根系去操做 # 查: # 1,全文搜索 year 將全部的year標籤所有找 # print(root.iter('year')) # print([i for i in root.iter('year')]) # 2,只找第一個,找到就返回 # print(root.find('country')) # 3,在root的子節點找,找全部的 # print(root.findall('country')) # 練習 # 找到標籤也能夠找到標籤相應的內容:tag,attrib,text # 1,找全部的rank標籤,以及 attrib 和 text (這裏利用列表推導式比較方便) # print([i for i in root.iter('rank')]) # [<Element 'rank' at 0x000001367D0D49F8>, <Element 'rank' at 0x000001367D0D4BD8>, <Element 'rank' at 0x000001367D0D4D68>] # print([i.attrib for i in root.iter('rank')]) # [{'updated': 'yes'}, {'updated': 'yes'}, {'updated': 'yes'}] # print([i.text for i in root.iter('rank')]) # ['2', '5', '69'] # 2,找到第二個country的 neighbor標籤以及他的屬性 # print([tag for tag in root.findall('country')][1].find('neighbor').attrib) # {'direction': 'N', 'name': 'Malaysia'} # 增 append # import xml.etree.ElementTree as ET # tree = ET.parse('a.xml') # 造成樹形結構 # root = tree.getroot() # 獲得樹的根系 # 給 year 大於2010年的全部標籤下面添加一個month標籤,屬性爲name:month 內容爲30days # for country in root.findall('country'): # for year in country.findall('year'): # if int(year.text) > 2010: # month = ET.Element('month') # month.text = '30days' # month.attrib = {'name': 'month'} # country.append(month) # tree.write('b.xml') #改 # import xml.etree.ElementTree as ET # tree = ET.parse('a.xml') # 造成樹形結構 # root = tree.getroot() # 獲得樹的根系 # 對全部的year屬性以及值進行修改 # for node in root.iter('year'): # new_year=int(node.text)+1 # node.text=str(new_year) # node.set('updated','yes') # node.set('version','1.0') # tree.write('test.xml') # 刪 # import xml.etree.ElementTree as ET # tree = ET.parse('a.xml') # 造成樹形結構 # root = tree.getroot() # 獲得樹的根系 # # # 將 rank值大於50的country標籤刪除 # 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) #打印生成的格式 本身建立xml文檔