双层装饰器
一个函数可以被多个装饰器装饰;
多层装饰器的本质是:嵌套;
执行规则是:解释自下而上,执行自上而下
•简单的用户权限验证程序:
USE_INFO = {} # 初始化一个字典,用户存放用户细信息 def check_login(func): # 最外层装饰器 def inner(*args, **kwargs): if USE_INFO.get(‘is_login‘, None): ret = func(*args, **kwargs) return ret else: print(‘请先登入‘) # 如果用户未登入则提示登入 return inner def check_admin(func): # 第二层装饰器 def inner(*args, **kwargs): if USE_INFO.get(‘user_type‘, None) == 2: # 用户权限是2则放行 ret = func(*args, **kwargs) return ret else: print(‘无权限‘) # 如果用户无权限则提示 return inner @check_login # 最外层装饰器 @check_admin # 第二层装饰器 def index(): # 最里层函数 print(‘index‘) # 验证用户和权限通过后输出 # 执行 while True: user_info = input(‘1、登入,2、查看信息、3、管理用户\n>>>‘) if user_info == ‘1‘: user_name = input(‘name>>:‘) USE_INFO[‘is_login‘] = user_name # 允许任何用户登入 if user_name == ‘alex‘: # 如果用户名为‘alex‘则给与权限 USE_INFO[‘user_type‘] = 2 index() if user_info == ‘2‘: index() if user_info == ‘3‘: index()
字符串的格式化
•%的常用方法
s = ‘Im %s‘ % ‘alex‘ Im alex # 输出 s = ‘Im %s,age%d‘ % (‘alex‘, 32) Im alex,age32 # 输出 s = ‘Im %(name)s,age %(age)d‘ % {‘name‘: ‘alex‘, ‘age‘: 31} Im alex,age 31 # 输出 s = ‘alex age %.2f‘ % 32.33333 # 小数点后两位,最后一位四舍五入 alex age 32.33 # 输出 s = ‘age %(age).2f‘ % {‘age‘: 123.245} age 123.25 # 输出 s = ‘age %(age).2f %%‘ % {‘age‘: 123.432432} # 输出% age 123.43 % # 输出
%
•format
s = ‘我是{},今年{}‘.format(‘alex‘, 32) 我是alex,今年32 # 输出 s = ‘我是{},今年{}‘.format(*[‘alex‘, 32]) 我是alex,今年32 # 输出 s = ‘我是{0},今年{1},我是{0}‘.format(‘alex‘, 32) 我是alex,今年32,我是alex # 输出 s = ‘我是{0},今年{1},我是{0}‘.format(*[‘alex‘, 32]) 我是alex,今年32,我是alex # 输出 s = ‘我是{name},今年{age}‘.format(name=‘alex‘,age=32) 我是alex,今年32 # 输出 s = ‘我是{name},今年{age}‘.format(**{‘age‘: 32, ‘name‘: ‘alex‘}) 我是alex,今年32 # 输出 s = ‘我是{0[0]},今年{0[1]},我是{0[0]}‘.format([‘alex‘, 32]) 我是alex,今年32,我是alex # 输出 s = ‘我是{:s},今年{:d},马内{:f}‘.format(‘alex‘, 32, 100.1) 我是alex,今年32,马内100.100000 # 输出 s = ‘我是{:s},年龄{:d}‘.format(*[‘alex‘, 32]) 我是alex,年龄32 # 输出 s = ‘我是{name:s},今年{age:d}‘.format(name=‘alex‘, age=32) 我是alex,今年32 # 输出 s = ‘我是{name:s},今年{age:d}‘.format(**{‘name‘: ‘alex‘, ‘age‘: 32}) 我是alex,今年32 # 输出 s = ‘numbers:{:b},{:o},{:d},{:x},{:X},{:%}‘.format(15, 15, 15, 15, 15, 15.555) numbers:1111,17,15,f,F,1555.500000% # 输出 s = ‘numbers:{0:b},{0:o},{0:d},{0:x},{0:X},{0:%}‘.format(15) numbers:1111,17,15,f,F,1500.000000% # 输出 s = ‘numbers:{num:b},{num:o},{num:d},{num:x},{num:X},{num:%}‘.format(num=15) numbers:1111,17,15,f,F,1500.000000% # 输出
format
生成器、迭代器、递归
•不会保存在内存中,而是返回一个对象,这个对象具有生成这些数的能力。当你去循环它的时候就会生成,这个东西叫做生成器
li = [1, 2, 3, 4, 5] s = filter(lambda a: a > 3, li) print(s) <filter object at 0x0000007A4C2DC668> # 输出,这个东西叫做生成器
•生成器:使用普通函数创造,在函数体中写入yield
def func(): # 定义一个生成器 yield 1 yield 2 yield 3 res = func() for i in res: print(i) # 输出 1 2 3
def func(): # 定义一个生成器 yield 1 yield 2 yield 3 res = func() print(res.__next__()) # 取第一个值 输出并保存yield的位置,下次继续从这个位置开始取值 print(res.__next__()) # 取第二个值 输出 print(res.__next__()) # 取第三个值 输出 1 2 3
yiled与__next__
def func(num): # 定义一个生成器 start = 0 while True: if start == num: return # 退出 yield start start += 1 res = func(3) print(res.__next__()) # 取值 print(res.__next__()) print(res.__next__()) 0 1 2
写个简单的range功能
•迭代器:给可以迭代的对象一个个取值,不断的调用__next__方法,直到达到某个条件就返回;我们利用迭代器去生成器里面取值,用__next__方法
def func(num): # 定义一个生成器 start = 1 res = 1 while True: if start <= num: res = res * start # 循环相乘 else: return res start += 1 res = func(5) # 定义从1乘到几 print(res) # 输出结果
简单连乘
•递归:本质就是一个函数不断调用另一个函数,也可以调用本身
def fun(n): n += 1 if n >= 5: return ‘end‘ return fun(n) res = fun(2) print(res) end # 输出
模块:
1、模块的简介
•模块可以是 文件夹 或者 .py文件,自定义模块名称决不能和内置模块重名!
•模块的分类:内置模块,自定义模块,第三方模块
•使用模块的原因是:将代码归类
•单模块的导入:import xxx,导入的依据是sys.path
•嵌套在文件夹下:from xxx import xxx; from xxx import xxx as ooo;from xxx import *意思是去这个模块中全部导入
•导入模块的搜索路径,搜索顺序从上往下找
import sys for i in sys.path: # python的搜索路径 print(i) # 打印结果 C:\Users\Administrator\AppData\Local\Programs\Python\Python35\python35.zip # 第一个目录是当前脚本所在的目录 C:\Users\Administrator\AppData\Local\Programs\Python\Python35\DLLs C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib C:\Users\Administrator\AppData\Local\Programs\Python\Python35 C:\Users\Administrator\AppData\Local\Programs\Python\Python35\lib\site-packages # 第三方模块的安装位置
2、requests模块
requests模块是专门做http请求的
•requests模块的安装
python -m pip install requests
# 天气的请求 import requests import json response = requests.get(‘http://wthrcdn.etouch.cn/weather_mini?city=淄博‘) # 请求页面 response.encoding = ‘utf-8‘ # 页面utf-8转换 dic = json.loads(response.text) # 序列化输出字符串 print(dic) # 输出
3、序列化和反序列化模块【json】和【pickle】
•json只能处理基本的数据类型,适合跨语言之间的交流;跨语言之间使用的一个规则:内部字符串必须使用双引号
import json s = ‘{"k1": 1}‘ # 单引号里面必须是双引号,单引号叫字符,双引号叫字符串,跨语言之间使用一个规则:内部字符串必须使用双引号 res = json.loads(s) # 将字符串转换为python的字典 print(res) {‘k1‘: 1} # 输出
import json re = json.load(open(‘file‘, ‘r‘, encoding=‘utf-8‘)) print(re, type(re)) # 输出 # load会顺便将字符串写入文件,比loads多出一步对文件的操作
4、time与datetime模块
import time print(time.time()) # 从1970年linux出现开始到现在的秒数(时间戳) print(time.ctime()) # 返回当前系统时间的字符串格式 print(time.ctime(time.time() - 86400)) # 减去一天的时间,转换为字符串 print(time.gmtime(time.time()-86400)) # 减去一天的时间,将时间戳转换为struct_time格式 print(time.localtime(time.time())) # 将本地系统的时间戳转换为struct_time格式 print(time.mktime(time.localtime())) # 将本地的时间struc_time转换为时间戳格式 print(time.strftime(‘%Y-%m-%d %H-%M-%S‘, time.localtime())) # 将本地的时间struc_time转换为指定字符串 print(time.strptime("2016-01-28", "%Y-%m-%d")) # 将字符串装换为struct_time格式
import datetime, time print(datetime.date.today()) # 输出今天的日期,格式为xx-xx-xx print(datetime.date.fromtimestamp(time.time())) # 将时间戳转化为xx-xx-xx print(datetime.datetime.now()) # 输出今天的日期、时间和时间戳,格式xx-xx-xx xx:xx:xx.xxxxxx print(datetime.datetime.now().timetuple()) # 返回struct_time格式 print(datetime.datetime.now().replace(2011, 1, 1)) # 替换指定值 print(datetime.datetime.strptime(‘21//11//06 16:30‘, ‘%d//%m//%y %H:%M‘)) # 将字符串装换为日期格式,间隔符随意 print(datetime.datetime.now() + datetime.timedelta(days=10)) # 比现在加10天 print(datetime.datetime.now() + datetime.timedelta(days=-10)) # 比现在减10天 print(datetime.datetime.now() + datetime.timedelta(hours=10)) # 比现在加10小时 print(datetime.datetime.now() + datetime.timedelta(seconds=120)) #比现在时间加120s
5、os模块
给系统或者程序提供需要的路径
import os print(os.path.abxpath(__file__)) # 获取自己的绝对路径 C:\Users\Administrator\PycharmProjects\s13\day5\day5_homework\conf\setting.py print(os.path.split(__file__)) # 分割成目录和文件,输出为tuple (‘C:/Users/Administrator/PycharmProjects/s13/day5/day5_homework/conf‘, ‘setting.py‘) print(os.path.dirname(__file__)) #获取分割后的目录,也就是split元组的第一个元素 C:/Users/Administrator/PycharmProjects/s13/day5/day5_homework/conf print(os.path.basepath(__file__)) # 获取文件名 setting.py print(os.getcwd()) # 获取当前的工作目录 C:\Users\Administrator\PycharmProjects\s13\day5\day5_homework\conf print(os.curdir) # 返回当前目录(‘.‘) .
6、logging模块
•简单logging
import logging logging.warning(‘user [alex] attempted wrong 3 times‘) logging.critical(‘servcer is down ‘) WARNING:root:user [alex] attempted wrong 3 times # 输出,默认是以管理员root执行的 CRITICAL:root:servcer is down
•往文件里面写入logging
import logging logging.basicConfig(filename=‘file‘,level=logging.INFO) # 只有比INFO级别高的级别才会写入file文件 logging.warning(‘user [alex] attempted wrong 3 times‘) logging.critical(‘servcer is down ‘) logging.debug(‘hahahahahha我是debug‘) WARNING:root:user [alex] attempted wrong 3 times # 文件内容 CRITICAL:root:servcer is down
•加入时间的logging
import logging logging.basicConfig(filename=‘file‘, level=logging.INFO,format=‘%(asctime)s %(message)s‘,datefmt=‘%m/%d/%Y %I:%M:%S %p‘) # 只有比INFO级别高的级别才会写入file文件,加上时间 logging.warning(‘user [alex] attempted wrong 3 times‘) logging.critical(‘servcer is down ‘) logging.debug(‘hahahahahha我是debug‘) 06/10/2016 11:14:41 PM user [alex] attempted wrong 3 times # 文件内容 06/10/2016 11:14:41 PM servcer is down
•将logging打印屏幕和文件