标签:
1 user_info = {} 2 3 4 def check_login(func): 5 def inner(*args, **kwargs): 6 if user_info.get(‘is_login‘, None): 7 ret = func(*args, **kwargs) 8 return ret 9 else: 10 print(‘请先登录...‘) 11 return inner 12 13 14 def check_user_type(func): 15 def inner(*args, **kwargs): 16 if user_info.get(‘user_type‘, None) == 1: 17 ret = func(*args, **kwargs) 18 return ret 19 else: 20 print(‘无权限查看...‘) 21 return inner 22 23 24 def login(): 25 user = input(‘请输入用户名: ‘) 26 if user == ‘admin‘: 27 user_info[‘is_login‘] = True 28 user_info[‘user_type‘] = 1 29 else: 30 user_info[‘is_login‘] = True 31 user_info[‘user_type‘] = 2 32 33 @check_login 34 @check_user_type 35 def index(): 36 """ 37 管理员的功能 38 :return: 39 """ 40 print(‘index‘) 41 42 @check_login 43 def home(): 44 """ 45 普通用户的功能 46 :return: 47 """ 48 print(‘home‘) 49 50 51 def main(): 52 while True: 53 int = input(‘1. 登录 2.查看信息 3.超级管理员\n>>>‘) 54 if int == ‘1‘: 55 login() 56 elif int == ‘2‘: 57 home() 58 elif int == ‘3‘: 59 index() 60 61 62 main()
注意:双层装饰器的执行过程
目前python支持百分号和format来完成字符串格式化的操作,百分号是2.0版本的。format方式是3.0版本的。
format支持的格式比百分号方式多。
1、百分号方式
1 str = "my name is %s, age is %d" 2 print(str%(‘john‘, 23))
%[(name)][flags][width].[precision]typecode
注:Python中百分号格式化是不存在自动将整数转换成二进制表示的方式
常用格式化
1 tpl = "i am %s" % "john" 2 3 tpl = "i am %s age %d" % ("john", 18) 4 5 tpl = "i am %(name)s age %(age)d" % {"name": "john", "age": 18} 6 7 tpl = "percent %.2f" % 99.97623 8 9 tpl = "i am %(pp).2f" % {"pp": 123.425556, } 10 11 tpl = "i am %.2f %%" %123.425556
format方式
1 str = "my name is {0}, age is {1}" 2 print(str.format(‘john‘,25))
[[fill]align][sign][#][0][width][,][.precision][type]
常用格式化:
1 tpl = "i am {}, age {}, {}".format("john", 25, ‘john‘) 2 3 tpl = "i am {}, age {}, {}".format(*["john", 25, ‘john‘]) 4 5 tpl = "i am {0}, age {1}, really {0}".format("john", 25) 6 7 tpl = "i am {0}, age {1}, really {0}".format(*["john", 25]) 8 9 tpl = "i am {name}, age {age}, really {name}".format(name="john", age=25) 10 11 tpl = "i am {name}, age {age}, really {name}".format(**{"name": "john", "age": 25}) 12 13 tpl = "i am {0[0]}, age {0[1]}, really {0[2]}".format([‘john‘, 25, ‘john‘], [11, 22, 33]) 14 15 tpl = "i am {:s}, age {:d}, money {:f}".format("john", 25, 88888.1) 16 17 tpl = "i am {:s}, age {:d}".format(*["john", 25]) 18 19 tpl = "i am {name:s}, age {age:d}".format(name="john", age=25) 20 21 tpl = "i am {name:s}, age {age:d}".format(**{"name": "john", "age": 25}) 22 23 tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2) 24 25 tpl = "numbers: {:b},{:o},{:d},{:x},{:X}, {:%}".format(15, 15, 15, 15, 15, 15.87623, 2) 26 27 tpl = "numbers: {0:b},{0:o},{0:d},{0:x},{0:X}, {0:%}".format(15) 28 29 tpl = "numbers: {num:b},{num:o},{num:d},{num:x},{num:X}, {num:%}".format(num=15)
更多格式化操作:https://docs.python.org/3/library/string.html
1、生成器Generators
生成器是一个有生成数据能力的对象。函数中如果用到了yield语法,那么这个函数就是一个生成器
特点:
yield 生成器的运行机制:
当你问生成器要一个数时,生成器会执行,直至出现 yield 语句,生成器把 yield 的参数给你,之后生成器就不会往下继续运行。 当你问他要下一个数时,他会从上次的状态。开始运行,直至出现yield语句,把参数给你,之后停下。如此反复,直至退出函数。
yield的使用:
1 def xf(): 2 yield 1 3 yield 2 4 yield 3 5 6 ret = xf() 7 print(ret.__next__()) 8 print(ret.__next__()) 9 print(ret.__next__()) 10 print(ret.__next__()) 11 12 结果: 13 14 1 15 2 16 3 17 File "/Users/TheOne/PycharmProjects/s13/day5/day5-课上/module.py", line 15, in <module> 18 print(ret.__next__()) 19 StopIteration
2、迭代器Iterators
迭代器是访问集合元素的一种方式。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退。
优点:
说明:for循环内部就是使用了next方法实现了遍历
1 def fo(arg): 2 arg += 1 3 if arg >= 5: 4 print(arg) 5 else: 6 return fo(arg) 7 fo(1) 8 9 结果: 10 5
如果函数包含了对其自身的调用,该函数就是递归的。
这里插入一些关于递归的网方解释,因为我是从网上搜到的这些内容:
(1)递归就是在过程或函数里调用自身;
(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
递归算法一般用于解决三类问题:
(1)数据的定义是按递归定义的。(比如Fibonacci函数)
(2)问题解法按递归算法实现。(回溯)
(3)数据的结构形式是按递归定义的。(比如树的遍历,图的搜索)
递归的缺点:递归算法解题的运行效率较低。在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出等。
参考:http://www.cnblogs.com/balian/archive/2011/02/11/1951054.html
为什么要有模块?
现在,我们写一些小项目时,都喜欢把所有的函数都放在一个文件里面(.py)。那么如果以后写大型项目,涉及到的函数可能有几百几千个,那个时候我们如果要更改某个函数的函数功能。缺点如下:
为了解决上面的难题,就用到了模块,模块和普通的程序一样,只不过模块文件中存放的全部都是业务处理的唯一功能,比如。用户操作的函数写在一个文件中,后台管理类的函数放在一个文件中。在主程序需要用到的时候,直接导入模块,执行对应的函数功能即可。优点如下:
导入模块的依据
模块的导入都是针对当前执行程序的目录而言的,python会先到当前程序执行的目录去查找模块,如果找不到,会接着到python定义的几个目录中去查找。如果还找不到,那么就会报错。
1 import sys 2 for i in sys.path: 3 print(i) 4 结果: 5 /Users/TheOne/PycharmProjects/s13/day5/day5-课上 6 /Users/TheOne/PycharmProjects/s13 7 /Library/Frameworks/Python.framework/Versions/3.5/lib/python35.zip 8 /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5 9 /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/plat-darwin 10 /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/lib-dynload 11 /Library/Frameworks/Python.framework/Versions/3.5/lib/python3.5/site-packages
python将所有的查找路径都放到了sys.path中以列表的方式保存,如果我们想到除以上路径外的其它地方加载模块,那么将模块的目录append到sys.path中即可。
模块名称的重要性
为了避免自定义模块和系统或第三方模块的name冲突,在自定义模块的时候,要尽量避开系统模块名 。或者为自定义模块赋予别名。
模块的导入方法
1、如果在同一目录下:
import 模块名
2、在当前目录下的其它目录
from 目录名 import 模块名
3、导入模块并命名别名
from 目录名 import 模块名 as 别名
json(适合所有程序语言,可以跨语言平台,用来在不同语言平台中交换数据。json只支持基本数据类型,即字符串,字典,列表,元素,数字等)
功能:
1 将python数据类型序列化成字符串 2 3 import json 4 dic = {‘name‘:‘john‘,‘age‘:25} 5 print(dic, type(dic)) 6 ret = json.dumps(dic) 7 print(ret, type(ret)) 8 结果: 9 {‘age‘: 25, ‘name‘: ‘john‘} <class ‘dict‘> 10 {"age": 25, "name": "john"} <class ‘str‘> 11 12 将字符串反序列化成python数据类型 13 import json 14 dic = ‘{"name":"john","age":25}‘ 15 print(dic, type(dic)) 16 ret = json.loads(dic) 17 print(ret, type(ret)) 18 结果: 19 {"name":"john","age":25} <class ‘str‘> 20 {‘age‘: 25, ‘name‘: ‘john‘} <class ‘dict‘>
注意:将字符串反序列化成python数据类型,一定要用单引号,否则报错。因为,在其他语言平台,单引号的叫字符,双引号的叫字符串
1 将python数据序列化到文件中 2 import json 3 dic = {"name":"john","age":25} 4 json.dump(dic, open(‘db‘, ‘w‘)) 5 6 从文件中反序列化到python 7 ret = json.load(open(‘db‘, ‘r‘)) 8 print(ret, type(ret)) 9 结果: 10 {‘name‘: ‘john‘, ‘age‘: 25} <class ‘dict‘>
pickle(支持python中的任意数据类型,基本数据类型和对象等。只能在python中使用,不支持跨语言平台使用)
功能和json一样,只不过pickle在序列化时,将python数据转换成了pickle的特定格式。
功能:
time&datetime模块
#_*_coding:utf-8_*_ import time import datetime print(time.clock()) #返回处理器时间,3.3开始已废弃 print(time.process_time()) #返回处理器时间,3.3开始已废弃 print(time.time()) #返回当前系统时间戳 print(time.ctime()) #输出Tue Jan 26 18:23:48 2016 ,当前系统时间 print(time.ctime(time.time()-86640)) #将时间戳转为字符串格式 print(time.gmtime(time.time()-86640)) #将时间戳转换成struct_time格式 print(time.localtime(time.time()-86640)) #将时间戳转换成struct_time格式,但返回 的本地时间 print(time.mktime(time.localtime())) #与time.localtime()功能相反,将struct_time格式转回成时间戳格式 #time.sleep(4) #sleep print(time.strftime("%Y-%m-%d %H:%M:%S",time.gmtime()) ) #将struct_time格式转成指定的字符串格式 print(time.strptime("2016-01-28","%Y-%m-%d") ) #将字符串格式转换成struct_time格式 #datetime module print(datetime.date.today()) #输出格式 2016-01-26 print(datetime.date.fromtimestamp(time.time()-864400) ) #2016-01-16 将时间戳转成日期格式 current_time = datetime.datetime.now() # print(current_time) #输出2016-01-26 19:04:30.335935 print(current_time.timetuple()) #返回struct_time格式 #datetime.replace([year[, month[, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]]]]]) print(current_time.replace(2014,9,12)) #输出2014-09-12 19:06:24.074900,返回当前时间,但指定的值将被替换 str_to_date = datetime.datetime.strptime("21/11/06 16:30", "%d/%m/%y %H:%M") #将字符串转换成日期格式 new_date = datetime.datetime.now() + datetime.timedelta(days=10) #比现在加10天 new_date = datetime.datetime.now() + datetime.timedelta(days=-10) #比现在减10天 new_date = datetime.datetime.now() + datetime.timedelta(hours=-10) #比现在减10小时 new_date = datetime.datetime.now() + datetime.timedelta(seconds=120) #比现在+120s print(new_date)
loggin模块
很多程序都有记录日志的需求,并且日志中包含的信息即有正常的程序访问日志,还可能有错误、警告等信息输出,python的logging模块提供了标准的日志接口,你可以通过它存储各种格式的日志,logging的日志可以分为 debug()
, info()
, warning()
, error()
and critical() 5个级别,
下面我们看一下怎么用。
loggin模块级别
Level | When it’s used |
---|---|
DEBUG |
Detailed information, typically of interest only when diagnosing problems. |
INFO |
Confirmation that things are working as expected. |
WARNING |
An indication that something unexpected happened, or indicative of some problem in the near future (e.g. ‘disk space low’). The software is still working as expected. |
ERROR |
Due to a more serious problem, the software has not been able to perform some function. |
CRITICAL |
A serious error, indicating that the program itself may be unable to continue running. |
如果想把日志写到文件里,也很简单
1 import logging 2 3 logging.basicConfig(filename=‘example.log‘,level=logging.INFO) 4 logging.debug(‘This message should go to the log file‘) 5 logging.info(‘So should this‘) 6 logging.warning(‘And this, too‘)
|
其中下面这句中的level=loggin.INFO意思是,把日志纪录级别设置为INFO,也就是说,只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里,在这个例子, 第一条日志是不会被纪录的,如果希望纪录debug的日志,那把日志级别改成DEBUG就行了。
1 logging.basicConfig(filename=‘example.log‘,level=logging.INFO)
感觉上面的日志格式忘记加上时间啦,日志不知道时间怎么行呢,下面就来加上!
1 import logging 2 logging.basicConfig(format=‘%(asctime)s %(message)s‘, datefmt=‘%m/%d/%Y %I:%M:%S %p‘) 3 logging.warning(‘is when this event was logged.‘) 4 5 #输出 6 12/12/2010 11:46:36 AM is when this event was logged.
如果想同时把log打印在屏幕和文件日志里,就需要了解一点复杂的知识 了
The logging library takes a modular approach and offers several categories of components: loggers, handlers, filters, and formatters.
1 import logging 2 3 #create logger 4 logger = logging.getLogger(‘TEST-LOG‘) 5 logger.setLevel(logging.DEBUG) 6 7 8 # create console handler and set level to debug 9 ch = logging.StreamHandler() 10 ch.setLevel(logging.DEBUG) 11 12 # create file handler and set level to warning 13 fh = logging.FileHandler("access.log") 14 fh.setLevel(logging.WARNING) 15 # create formatter 16 formatter = logging.Formatter(‘%(asctime)s - %(name)s - %(levelname)s - %(message)s‘) 17 18 # add formatter to ch and fh 19 ch.setFormatter(formatter) 20 fh.setFormatter(formatter) 21 22 # add ch and fh to logger 23 logger.addHandler(ch) 24 logger.addHandler(fh) 25 26 # ‘application‘ code 27 logger.debug(‘debug message‘) 28 logger.info(‘info message‘) 29 logger.warn(‘warn message‘) 30 logger.error(‘error message‘) 31 logger.critical(‘critical message‘)
python-day5-装饰器补充、模块、字符串格式化和序列化
标签:
原文地址:http://www.cnblogs.com/gouyc/p/5567836.html