一 软件的开发规范
基本的目录结构: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:级别
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 '''
logger:对象。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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')
Formatter的用法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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') 重要,重要,重要!!!
logger的继承
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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继承
logging的配置
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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配置文件
使用:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 使用
diango的配置
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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的日志会被打印
可在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 |
用户输出的消息 |
打印终端时又保存到文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#_*_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') 即打印到终端又打印到文件
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