Decorator:多层装饰器
#双层装饰器(用户登录,权限)
#多层: 调用从最外层到最内层函数,返回值则从最内到最外层函数
USER_INFO = {}
#USER_INFO['is_login'] = True
#USER_INFO['user_type'] = 2
def check_login(func):
def inner(*args,**kwargs):
if USER_INFO.get('is_login',None):
ret = func(*args,**kwargs)
return ret
else:
print("please login")
return inner
def check_admin(func):
def inner(*args, **kwargs):
if USER_INFO.get('user_type',None) == 2:
ret = func(*args, **kwargs)
return ret
else:
print("You are not allowed to do this")
return inner
@check_login
@check_admin
def index():
print("index")
index()
Packages:创建与运用
? 1.创建一个名为s4.py的python文件,写入以下函数:
def login():
print("login")
2. 在另一个python文件中以模块形式import s4文件,并调用login函数:
import s4 #加载所有s4文件中内容到内存
s4.login()
! 注意:创建模块时不能和内置模块名重名;
导入模块时:
若导入单模块: import xxx
嵌套在文件夹下:
form xxx import yyy
from xxx import yyy as zzz
requests:用get获取网址信息,打印响应内容、响应状态码
import requests
url = 'http://q.stock.sohu.com/cn/bk_2011.shtml'
r = requests.get(url)
print(r.text)
print(r.status_code)
序列化:常用模块为json与pickle:
- json,用于字符串 和 python数据类型间进行转换
- pickle,用于python特有的类型 和 python的数据类型间进行转换
json - dumps返回的是一个字符串,load和loads则会返回python的对象。
import json
dic={'k1':'v1'}
print(dic,type(dic))
#将python基本数据类型转成字符串形式
result = json.dumps(dic)
print(result ,type(result))
s1 = '{"k1":123}'
#将python字符串形式转化成基本数据类型
dic= json.loads(s1)
print(dic,type(dic))
#返回信息原本是字符串类型(字典形态)
response = requests.get('http://wthrcdn.etouch.cn/weather_mini?city=北京')
response.encoding ='utf-8'
#返回信息自动转化为字典
dic = json.loads(response.text)
print(type(dic))
r= json.dumps([11,22,33])
#通过loads去翻序列的时候一定要里面是双引号
li = '["eric","alex"]'
ret = json.loads(li)
print(ret,type(ret))
#比加s的多一步操作,把序列化的字符串写到另一个文件(写\读文件操作)
li = '["eric","alex"]'
f1 = json.dump(li,open("db1","w"))
f2 = json.load(open("db1","r"))
Pickle
import pickle
li = [11,22,33]
r= pickle.dumps(li)
print(r)
result = pickle.loads(r)
print(result)
li =[11,22,33]
pickle.dump(li,open('db','wb'))
json与pickle比较: -reference:https://docs.python.org/3/library/pickle.html
- JSON是文本形式的存储,Pickle则是二进制形式(至少常用二进制)
- JSON是人可读的,Pickle不可读
- JSON广泛应用于除Python外的其他领域,Pickle是Python独有的。
- JSON只能dump一些python的内置对象,Pickle可以存储几乎所有对象。
time与datetime模块:time一般用来取时间戳;datetime一般取日期
import time
#1970年开始,unix系统上线(linux雏形),到现在的秒数
print(time.time()) #1465726407.219118
tu = (2016,6,16,2,14,33,22,22,33)
print(time.mktime(tu)) #时间对象转换成时间戳(1970年到现在):1466010873.0
print(time.ctime()) #返回当前时间字符串形式:Sun Jun 12 18:13:27 2016
print(time.gmtime())
print(time.localtime())
#打印结果均为e.struct_time(tm_year=2016, tm_mon=6, tm_mday=12, tm_hour=10, tm_min=15, tm_sec=9, tm_wday=6, tm_yday=164, tm_isdst=0)
time.sleep(4) #睡眠4秒钟,阻塞
tm = time.strftime("%Y-%m-%d", time. gmtime())
import datetime
print(datetime.date.today()) #2016-06-12
print(datetime.date.fromtimestamp(10000000))#时间戳转成日期格式:1970-04-27
current_time = datetime.datetime.now() #精确到毫秒
#进行时间运算
datetime.datetime.now()-datetime.timedelta(hours= 10) #比现在加10小时
print(current_time.replace(2014,6,9)) #直接更改时间:2014-06-09 18:18:45.366615
logging模块: 可以通过以下几类存储日志
?
import logging
logging.warning("User tried three times")
logging.critical("server is down")
写入文件:其中下面这句中的level=loggin.INFO意思是把日志纪录级别设置为INFO;只有比日志是INFO或比INFO级别更高的日志才会被纪录到文件里
import logging
logging.basicConfig(filename='example.log',level= logging.INFO)
logging.debug('This message should go to the log file')
logging.info('So should this')
logging.warning('And this, too')
? 加上时间:
import logging
logging.basicConfig(format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
logging.warning('is when this event was logged.')
格式化:
Format与占位符%s,%d-format要比%s %d功能强大很多
占位符%s,%d:
#%s文字
s = "I am %s"%("Alex")
print(s)
#%d数字
s = "I am %s, %d years old"%("Alex",18)
print(s)
#用字典传值
s = "I am %(name)s,%(age)d years old"%{"name":"Alex","age":18}
print(s)
#保留n位小数(%.nf)
s = "percent %.2f" % 99.6323
print(s)
#用字典传值,保留n位小数
s = "%(pp).2f"% {"pp":132.86346}
print(s)
#当格式化时,字符串中如果已经出现占位符,需要用两个%,才能在输出的时候看见一个%
s = "%(pp).2f %%"% {"pp":132.86346}
print(s)
Format:填充字符,居中,%s自动转换. 二进制八进制0x,0b需不需要:
s1 = "adjh{0}s{0}d{1}mb".format(123,"Alex")
print(s1)
s1 = "----{name:s}-----{age:d}---".format(name = "alex", age = 18)
print(s1)
#填充只能填一个字符,20个a填充;"Alex"居中,数字前面加正号
s1 ="{:a^20s}{:+d}".format("Alex",18)
print(s1)
#基础
s1 = "i am {},age{}{}".format("seven",18,'alex')
print(s1)
#用列表传值时要在列表前加一个*
s1 = "i am {},age{}{}".format(*["seven",18,'alex'])
print(s1)
#数字体现顺序
s1 = "i am {0},age{1}{0}".format("seven",18)
print(s1)
#用列表传值,数字体现列表中顺序
s1 = "i am {0},age{1}{0}".format(*["seven",18,'alex'])
print(s1)
s1 = "i am {name},age{age}{name}".format(name = "seven",age = 18)
print(s1)
#用字典传的时候要在字典前面加两个*
s1 = "i am {name},age{age}{name}".format(**{"name" : "seven", "age" : 18})
print(s1)
#列表中的列表,体现顺序
s1 = "i am {0[0],age{0[1],really{0[2]}".format([1,2,3],[2,3,4])
print(s1)
#:b转为二进制;:%自动加上百分号
s1 = "numbers{:b},{:o},{:d},{:x},{:x},{:%}".format(15,15,15,15,15,15.2554643,2)
print(s1)
生成器:
一个函数调用时返回一个迭代器,那这个函数就叫做生成器(generator);如果函数中包含yield语法,那这个函数就会变成生成器;
#生成器:函数出现yield
def func():
print("111")
yield 1
print("222")
yield 2
print("333")
yield 3
ret =func()
#进入函数找到yield(保存上一次执行的位置),获取yield后面数据
r1 = ret.__next__()
print(r1)
r2 = ret.__next__()
print(r2)
r3 = ret.__next__()
print(r3)
递归:
(1)递归就是在过程或函数里调用自身;
(2)在使用递归策略时,必须有一个明确的递归结束条件,称为递归出口。
?
def d():
return "123"
def c():
r = d()
return r
def b():
r = c()
return r
def a():
r = b()
return r
print(a())
?
def func(n):
print("---") #六条线
n+=1
if n >= 4:
return 'end'
return func(n)
func(1)
print(func(1))