闭包
- 多层函数的嵌套
- 内部函数用到外部函数的变量
# 闭包 一个函数里面套了另外一个函数的定义
def line_6(k, b):
def create_y(x):
print(k*x + b)
return create_y
line_6_1 = line_6(1, 2)
line_6_1(0)
line_6_1(1)
line_6_1(2)
line_6_2 = line_6(11, 22)
line_6_2(0)
line_6_2(1)
line_6_2(2)
函数、匿名函数、闭包、对象当做实参的区别
- 匿名函数嫩能够完成基本的简单功能,传递的是这个函数的引用,只有功能。
- 普通函数能够完成较为复杂的功能,传递的是这个函数的引用,只有功能
- 闭包能够将较为复杂的功能,传递的是闭包中的函数意义数据,因此传递是功能+数据
- 对象能够完成最为复杂的功能,传递是很多数据+很多功能,因此传递是功能+数据
闭包修改数据
x = 300
def test1():
x = 200
def test2():
nonlocal x
print("----1----x=%d" % x)
x = 100
print("----2----x=%d" % x)
return test2
t1 = test1()
t1()
装饰器
装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率如虎添翼。
装饰器实现原理例子
def set_func(func):
def call_func():
print("--这是权限验证1")
func()
return call_func
def test1():
print("---test1----")
test1 = set_func(test1)
# 在不修改原来函数的基础上,给函数添加了验证功能
test1()
def set_func(func):
def call_func():
print("--这是权限验证1")
func()
return call_func
@set_func
# 等价于test1 = set_func(test1)
def test1():
print("---test1----")
test1()
有参数的闭包
def set_func(func):
def call_func(a):
print("--这是权限验证1")
func(a)
return call_func
@set_func
def test1(num):
print("----test1----%d" % num)
test1(100)
装饰器可以装饰多个函数
def set_func(func):
def call_func(a):
print("--这是权限验证1")
func(a)
return call_func
@set_func
def test1(num):
print("----test1----%d" % num)
@set_func
def test2(num):
print("----test2----%d" % num)
test1(100)
test2(200)
不定长参数的函数装饰
def set_func(func):
def call_func(*args, **kwargs):
print("--这是权限验证1")
func(*args, **kwargs)
return call_func
@set_func
def test1(num, *args, **kwargs):
print("----test1----%d" % num)
print("----test1----", args)
print("----test1----", kwargs)
test1(100)
test1(200, 300)
对应有返回值函数进行装饰、通用装饰器
def set_func(func):
def call_func(*args, **kwargs):
print("--这是权限验证1")
return func(*args, **kwargs)
return call_func
@set_func
def test1(num, *args, **kwargs):
print("----test1----%d" % num)
print("----test1----", args)
print("----test1----", kwargs)
return "ok"
@set_func
def test2():
pass
ret = test1(100)
print(ret)
ret = test2()
print(ret)
多个装饰器对同一个函数装饰
def add_auth(func):
def call_func(*args, **kwargs):
print("--这是权限验证1")
return func(*args, **kwargs)
return call_func
def add_auth2(func):
def call_func(*args, **kwargs):
print("--这是权限验证2")
return func(*args, **kwargs)
return call_func
@add_auth
@add_auth2
def test1():
print("----test1----");
test1()
def set_func_2(func):
def call_func():
return "<td>" + func() + "</td>"
return call_func
def set_func_1(func):
def call_func():
return "<h1>" + func() + "</h1>"
return call_func
@set_func_1 # get_str = set_func_1(get_str)
@set_func_2 # get_str = set_func_2(get_str)
def get_str():
return "haha"
print(get_str())
使用类当做装饰器
class Test(object):
def __init__(self, func):
self.func = func
def __call__(self):
print("这里是装饰器添加的功能...")
return self.func()
@Test # get_str = Test(get_str)
def get_str():
return "haha"
print(get_str())
带有参数的装饰器
def set_level(level_num):
def set_func(func):
def call_func(*args, **kwargs):
if level_num == 1:
print("----权限验证1----")
elif level_num == 2:
print("----权限验证2----")
return func()
return call_func
return set_func
@set_level(1)
# 调用set_func并且将1当做实参传递
# 用上一步调用的返回值当做装饰器对test1函数进行装饰
def test1():
print("----test1----")
return "ok"
@set_level(2)
def test2():
print("----test2----")
return "ok"
test1()
test2()
用装饰器完成路由功能
import re
URL_FUNC_DICT = dict()
def route(url):
def set_func(func):
URL_FUNC_DICT[url] = func
def call_func(*args, **kwargs):
return func(*args, **kwargs)
return call_func
return set_func
@route("/index.py")
def index():
with open("./templates/index.html") as f:
content = f.read()
my_stock_info = "哈哈哈哈 这是你的本月名称....."
content = re.sub(r"\{%content%\}", my_stock_info, content)
return content
@route("/center.py")
def center():
with open("./templates/center.html") as f:
content = f.read()
my_stock_info = "这里是从mysql查询出来的数据。。。"
content = re.sub(r"\{%content%\}", my_stock_info, content)
return content
def application(env, start_response):
start_response('200 OK', [('Content-Type', 'text/html;charset=utf-8')])
file_name = env['PATH_INFO']
# file_name = "/index.py"
"""
if file_name == "/index.py":
return index()
elif file_name == "/center.py":
return center()
else:
return 'Hello World! 我爱你中国....'
"""
try:
return URL_FUNC_DICT[file_name]()
except Exception as ret:
return "产生了异常: %s" % str(ret)
伪静态、静态和动态的区别
静态URL
静态URL类似“域名/new/2015-5-18/110.html”我们一般称为静态URL,每个网页有真实的物理路径,也就是真实存在服务器里的。
动态URL
动态URL类似“域名/newsmore.asp?id=5"带有?的url,我们一般称为动态网址,每个url只是一个逻辑地址,并不是真实物理存在服务器硬盘里的。
伪静态URL
伪静态URL类似”域名/courese/74.html"这个URL和真静态URL类似。他是通过伪静态规则把动态URL伪装成静态网址。也是逻辑地址,不存在物理地址
url编码
import urllib.parse
def main():
result = urllib.parse.quote("中国")
print(result)
result = urllib.parse.unquote("%E4%B8%AD%E5%9B%BD")
print(result)
if __name__ == '__main__':
main()
log日志功能
1.日志级别
日志一共分为5个登记,从低到高分别是:
- DEBUG
- INFO
- WARNING
- ERROR
- CRITICAL
说明:
- DEBUG:详细的信息,通常只会出现在诊断问题上
- INFO:确认一切按预期运行
- WARNING:一个迹象表明,一些意想不到的事发生了,或表明一些问题再不久的将来
- ERROR:更严重的问题,软件没能执行一些功能
- CRITICAL:一个严重的错误,表明程序本身可能无法继续运行
这5个登记,也分别对应5中打日志的方法:debug、info、warnig、error、critical。默认的是WARNING,当在WARNING或者之上才被跟踪
日志输出
有两种方式记录跟踪,一种输出控制台,另一种记录到文件中,如日志文件。
输出到控制台
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
# 开始使用log功能
logging.debug("这是 logging debug message")
logging.info("这是 logging info message")
logging.warning("这是 logging warning message")
logging.error("这是 logging error message")
logging.critical("这是 logging critical message")
将日志输出到文件
可以将日志输出到文件,只需要在logging.basicConfig函数中设置好输出文件的文件名和文件的模式。
import logging
logging.basicConfig(level=logging.INFO,
filename="./log.txt",
filemode="w",
format="%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
# 开始使用log功能
logging.debug("这是 logging debug message")
logging.info("这是 logging info message")
logging.warning("这是 logging warning message")
logging.error("这是 logging error message")
logging.critical("这是 logging critical message")
既可以把日志输出到控制台,还要写入日志文件
import logging
# 第一步,建立一个logger
logger = logging.getLogger()
logger.setLevel(logging.INFO) # log等级总开关
# 第二步,创建一个handler,用于写入日志
logfile = "./log.txt"
fh = logging.FileHandler(logfile, mode="a") # open模式
fh.setLevel(logging.DEBUG) # 输出到file的log等级的开关
# 第三步, 再创建一个handler,用于输出到控制台
ch = logging.StreamHandler()
ch.setLevel(logging.WARNING) # 输出到console的log等级的开关
# 第四步,定义handler的输出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh.setFormatter(formatter)
ch.setFormatter(formatter)
# 第五步,将logger添加到handler里面
logger.addHandler(fh)
logger.addHandler(ch)
# 日志
logger.debug("这是 logging debug message")
logger.info("这是 logging info message")
logger.warning("这是 logging warning message")
logger.error("这是 logging error message")
logger.critical("这是 logging critical message")
网友评论