重修課程day26(面向對象6之反射,內置函數和常用模塊)
一 軟件的開發規範
基本的目錄結構:bin目錄:裏面寫start.py文件,啟動程序。將當前的項目目錄添加到sys.path,調用core文件下的所有腳本。
core目錄:放一些主腳本文件,跟類相關的文件放在裏面。在創建一個core.py文件放一些與類不相關的內容。我們寫的所有代碼,導入模塊都是從當前項目的路徑開始導入的。
db目錄:存放一些數據
lib目錄:粘貼別人寫好的模塊
log目錄:日誌目錄
conf目錄:放一些用戶的配置文件
模塊和包是好了給別人來調用的;項目是自己寫好的一個程序
二 反射
1 什麽叫做反射:講一個字符串的數據類型變成一個真實存在於這個程序的真實變量,並且還能使用它
getattr:獲取:操作一個對象屬性和方法,不通過對象來調用而是通過一個字符串來調用
hasattr:判斷屬性和方法是否真實存在於這個類的裏面,常用於和getattr合用
setattr:添加屬性和方法,創建方法時需要手動的傳入一個對象參數。建議不要用setattr添加方法
delattr:刪除屬性和方法
2 反射的應用場景:1 類名調用方法和屬性(靜態類屬性,靜態類方和類方法)
2 對象調用屬性和方法(對象屬性和普通方法(self))
3 模塊名調用屬性和方法(變量函數)
4 在自己模塊種調用屬性和方法(變量函數)
三 內置函數
isinstance:判斷一個對象是不是這個類的實例,如果這個類為父類,那麽這個對象也是其父類。
issubclass:判斷一個類是不是一個類的子類
__str__和__repr__:字符串格式化,str只調自己,repr可以調用str和repr。
__format__:依賴format_spec字符串格式化。
__del__:析構方法,清理內存,主動觸發刪除對象
__call__:
__len__:計算長度
__hash__:hash一個值
__eq__:對象比較,雙等號觸發eq
item 系列:整個系列與中括號相關聯 (__getitem__,__setitem__,__delitem__)
__new__:新創建一個裸著得對象,這個對象就是self
其他函數——》內置函數——》類的內置方法
單例模式:由於你的一些需求,從始至終只實例了一個對象,他的屬性會隨著你的改變而改變。
四 常用模塊
1 hashlib模塊:摘要算法。
作用:檢驗文件的一致性
常用的是:md5()算法:支持一部分一部分的摘要和一次性的摘要,結果都是一樣的。只能摘要成密文,不能反解
sha()算法;sha算法越長越慢
hashlib.md5():加密文件
update:括號裏跟上要加密的內容,還需要轉碼
hexdigest:消化系統,消化的結果就是想要的結果
暴力破解,也叫撞庫
加鹽:在需要摘要的內容加密之前加上一段內容,這就叫做加鹽。
檢測文件的一致性:文字文件一行一行的讀取;視頻文件是按照字節讀取
2 logging模塊:日誌模塊,用於便捷記錄日誌且線程安全的模塊
hasicconfig:級別
1 import logging 2 3 logging.debug(‘調試debug‘) 4 logging.info(‘消息info‘) 5 logging.warning(‘警告warn‘) 6 logging.error(‘錯誤error‘) 7 logging.critical(‘嚴重critical‘) 8 9 ‘‘‘ 10 WARNING:root:警告warn 11 ERROR:root:錯誤error 12 CRITICAL:root:嚴重critical 13 ‘‘‘View Code
logger:對象。
1 #======介紹 2 可在logging.basicConfig()函數中可通過具體參數來更改logging模塊默認行為,可用參數有 3 filename:用指定的文件名創建FiledHandler(後邊會具體講解handler的概念),這樣日誌會被存儲在指定的文件中。 4 filemode:文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。 5 format:指定handler使用的日誌顯示格式。 6 datefmt:指定日期時間格式。 7 level:設置rootlogger(後邊會講解具體概念)的日誌級別 8 stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件,默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。 9 10 11 format參數中可能用到的格式化串: 12 %(name)s Logger的名字 13 %(levelno)s 數字形式的日誌級別 14 %(levelname)s 文本形式的日誌級別 15 %(pathname)s 調用日誌輸出函數的模塊的完整路徑名,可能沒有 16 %(filename)s 調用日誌輸出函數的模塊的文件名 17 %(module)s 調用日誌輸出函數的模塊名 18 %(funcName)s 調用日誌輸出函數的函數名 19 %(lineno)d 調用日誌輸出函數的語句所在的代碼行 20 %(created)f 當前時間,用UNIX標準的表示時間的浮 點數表示 21 %(relativeCreated)d 輸出日誌信息時的,自Logger創建以 來的毫秒數 22 %(asctime)s 字符串形式的當前時間。默認格式是 “2003-07-08 16:49:45,896”。逗號後面的是毫秒 23 %(thread)d 線程ID。可能沒有 24 %(threadName)s 線程名。可能沒有 25 %(process)d 進程ID。可能沒有 26 %(message)s用戶輸出的消息 27 28 29 30 31 #========使用 32 import logging 33 logging.basicConfig(filename=‘access.log‘, 34 format=‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, 35 datefmt=‘%Y-%m-%d %H:%M:%S %p‘, 36 level=10) 37 38 logging.debug(‘調試debug‘) 39 logging.info(‘消息info‘) 40 logging.warning(‘警告warn‘) 41 logging.error(‘錯誤error‘) 42 logging.critical(‘嚴重critical‘)View Code
Formatter的用法
Logger is also the first to filter the message based on a level — if you set the logger to INFO, and all handlers to DEBUG, you still won‘t receive DEBUG messages on handlers — they‘ll be rejected by the logger itself. If you set logger to DEBUG, but all handlers to INFO, you won‘t receive any DEBUG messages either — because while the logger says "ok, process this", the handlers reject it (DEBUG < INFO). #驗證 import logging form=logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S %p‘,) ch=logging.StreamHandler() ch.setFormatter(form) # ch.setLevel(10) ch.setLevel(20) l1=logging.getLogger(‘root‘) # l1.setLevel(20) l1.setLevel(10) l1.addHandler(ch) l1.debug(‘l1 debug‘) 重要,重要,重要!!!View Code
logger的繼承
import logging formatter=logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S %p‘,) ch=logging.StreamHandler() ch.setFormatter(formatter) log1=logging.getLogger(‘root‘) log2=logging.getLogger(‘root.child1‘) log3=logging.getLogger(‘root.child1.child2‘) log1.setLevel(10) log2.setLevel(10) log3.setLevel(10) log1.addHandler(ch) log2.addHandler(ch) log3.addHandler(ch) log1.debug(‘log1 debug‘) log2.debug(‘log2 debug‘) log3.debug(‘log3 debug‘) ‘‘‘ 2017-07-28 22:22:05 PM - root - DEBUG -test: log1 debug 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test: log2 debug 2017-07-28 22:22:05 PM - root.child1 - DEBUG -test: log2 debug 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug 2017-07-28 22:22:05 PM - root.child1.child2 - DEBUG -test: log3 debug ‘‘‘ part4:logger繼承View Code
logging的配置
1 """ 2 logging配置 3 """ 4 5 import os 6 import logging.config 7 8 # 定義三種日誌輸出格式 開始 9 10 standard_format = ‘[%(asctime)s][%(threadName)s:%(thread)d][task_id:%(name)s][%(filename)s:%(lineno)d]‘ 11 ‘[%(levelname)s][%(message)s]‘ #其中name為getlogger指定的名字 12 13 simple_format = ‘[%(levelname)s][%(asctime)s][%(filename)s:%(lineno)d]%(message)s‘ 14 15 id_simple_format = ‘[%(levelname)s][%(asctime)s] %(message)s‘ 16 17 # 定義日誌輸出格式 結束 18 19 logfile_dir = os.path.dirname(os.path.abspath(__file__)) # log文件的目錄 20 21 logfile_name = ‘all2.log‘ # log文件名 22 23 # 如果不存在定義的日誌目錄就創建一個 24 if not os.path.isdir(logfile_dir): 25 os.mkdir(logfile_dir) 26 27 # log文件的全路徑 28 logfile_path = os.path.join(logfile_dir, logfile_name) 29 30 # log配置字典 31 LOGGING_DIC = { 32 ‘version‘: 1, 33 ‘disable_existing_loggers‘: False, 34 ‘formatters‘: { 35 ‘standard‘: { 36 ‘format‘: standard_format 37 }, 38 ‘simple‘: { 39 ‘format‘: simple_format 40 }, 41 }, 42 ‘filters‘: {}, 43 ‘handlers‘: { 44 #打印到終端的日誌 45 ‘console‘: { 46 ‘level‘: ‘DEBUG‘, 47 ‘class‘: ‘logging.StreamHandler‘, # 打印到屏幕 48 ‘formatter‘: ‘simple‘ 49 }, 50 #打印到文件的日誌,收集info及以上的日誌 51 ‘default‘: { 52 ‘level‘: ‘DEBUG‘, 53 ‘class‘: ‘logging.handlers.RotatingFileHandler‘, # 保存到文件 54 ‘formatter‘: ‘standard‘, 55 ‘filename‘: logfile_path, # 日誌文件 56 ‘maxBytes‘: 1024*1024*5, # 日誌大小 5M 57 ‘backupCount‘: 5, 58 ‘encoding‘: ‘utf-8‘, # 日誌文件的編碼,再也不用擔心中文log亂碼了 59 }, 60 }, 61 ‘loggers‘: { 62 #logging.getLogger(__name__)拿到的logger配置 63 ‘‘: { 64 ‘handlers‘: [‘default‘, ‘console‘], # 這裏把上面定義的兩個handler都加上,即log數據既寫入文件又打印到屏幕 65 ‘level‘: ‘DEBUG‘, 66 ‘propagate‘: True, # 向上(更高level的logger)傳遞 67 }, 68 }, 69 } 70 71 72 def load_my_logging_cfg(): 73 logging.config.dictConfig(LOGGING_DIC) # 導入上面定義的logging配置 74 logger = logging.getLogger(__name__) # 生成一個log實例 75 logger.info(‘It works!‘) # 記錄該文件的運行狀態 76 77 if __name__ == ‘__main__‘: 78 load_my_logging_cfg() 79 80 logging配置文件View Code
使用:
1 """ 2 MyLogging Test 3 """ 4 5 import time 6 import logging 7 import my_logging # 導入自定義的logging配置 8 9 logger = logging.getLogger(__name__) # 生成logger實例 10 11 12 def demo(): 13 logger.debug("start range... time:{}".format(time.time())) 14 logger.info("中文測試開始。。。") 15 for i in range(10): 16 logger.debug("i:{}".format(i)) 17 time.sleep(0.2) 18 else: 19 logger.debug("over range... time:{}".format(time.time())) 20 logger.info("中文測試結束。。。") 21 22 if __name__ == "__main__": 23 my_logging.load_my_logging_cfg() # 在你程序文件的入口加載自定義logging配置 24 demo() 25 26 使用View Code
diango的配置
import logging ‘‘‘ 一:如果不指定filename,則默認打印到終端 二:指定日誌級別: 指定方式: 1:level=10 2:level=logging.ERROR 日誌級別種類: CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0 三:指定日誌級別為ERROR,則只有ERROR及其以上級別的日誌會被打印 ‘‘‘ logging.basicConfig(filename=‘access.log‘, format=‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S %p‘, level=10) logging.debug(‘debug‘) logging.info(‘info‘) logging.warning(‘warning‘) logging.error(‘error‘) logging.critical(‘critical‘) logging.log(10,‘log‘) #如果level=40,則只有logging.critical和loggin.error的日誌會被打印View Code
可在logging.basicConfig()函數中通過具體參數來更改logging模塊默認行為,可用參數有
filename:用指定的文件名創建FiledHandler(後邊會具體講解handler的概念),這樣日誌會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。
format:指定handler使用的日誌顯示格式。
datefmt:指定日期時間格式。
level:設置rootlogger(後邊會講解具體概念)的日誌級別
stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件,默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。點擊查看更詳細
日誌格式
%(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 |
用戶輸出的消息 |
打印終端時又保存到文件
#_*_coding:utf-8_*_ __author__ = ‘Linhaifeng‘ import logging formater=logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s‘, datefmt=‘%Y-%m-%d %H:%M:%S %p‘,) fh=logging.FileHandler(‘aaaaaaaaaaaa.log‘) ch=logging.StreamHandler() fh.setFormatter(formater) ch.setFormatter(formater) log1=logging.getLogger() log1.setLevel(logging.ERROR) log1.addHandler(fh) log1.addHandler(ch) log1.debug(‘deubug‘) log1.info(‘info‘) log1.warning(‘warn‘) log1.error(‘erro‘) log1.critical(‘critical‘) 即打印到終端又打印到文件View Code
3 configparser模塊:配置文件,必須要有DEFAULI這個節
configpaser.configpaser:生成文檔
sections:打印所有的節
config[節][key]:取具體的值
不管打印任何的節,SEFAULI這個節的內容都會打印出來
config.get:獲取具體的值config.items:打印節下面的所有的內容,同時還會打印出SEFAULI下面的所有內容。
add_section:增加節
remove_section:刪除一個節
remove_option:刪除節下面的以惡搞內容
本篇博客詳情:http://www.cnblogs.com/Eva-J/articles/7351812.html
http://www.cnblogs.com/Eva-J/articles/7228075.html
重修課程day26(面向對象6之反射,內置函數和常用模塊)