本系列博文基于廖雪峰老师的官网Python教程,笔者在大学期间已经阅读过廖老师的Python教程,教程相当不错,官网链接: 廖雪峰官方网站.请需要系统学习Python的小伙伴到廖老师官网学习,笔者的编程环境是Anaconda+Pycharm,Python版本:Python3.
1.装饰器
# 函数是一个对象,函数对象可以被赋值给变量,即通过变量可以调用该函数;
def time():
print("1min.")
f = time
print("通过变量调用函数:")
f()
# 函数对象有一个__name__属性,可以拿到函数的名字;
print("通过name属性,得到函数的名字为:",time.__name__)
print("变量通过name属性,可以得到函数的名字:",f.__name__)
print("------------------------------------------------------------------")
# 增强time()函数的功能,如:在函数调用前后自动打印日志,
# 但不希望修改time()函数的定义,这种在代码运行期间动态增加功能的方式,称为"装饰器(Decorator)";
# 定义一个能打印日志的decorator:
def log(func): # 接受一个函数作为参数,并返回一个函数;
def wrapper(*args,**kw):
print("Call %s():" % func.__name__)
return func(*args,**kw)
return wrapper
# 借助Python的@语法,把decorator置于函数定义处
@log
def time():
print("One min.")
# 调用time函数
print("添加了log的time函数:")
time()
print("没有添加functoos.wrap的time.__name__:",time.__name__)
print("------------------------------------------------------------------")
# 1.time() <===> time = log(time)
# 2.log()是一个decorator,返回一个函数,因此原来的time()函数仍然存在,
# 现在同名的time变量指向新的函数,调用time()将执行新函数,
# 即在log()函数中返回的wrapper()函数;
# 3.wrapper()函数的参数定义(*args,**kw),因此,wrapper()函数可以接受任意参数的调用,
# 在wrapper()函数内,先打印日志,再调用原始函数;
# 实例:自定义log的文本
def log(text):
def decorator(func):
def wrapper(*args,**kw):
print("%s %s():" % (text,func.__name__))
return func(*args,**kw)
return wrapper
return decorator
# 调用方法
@log("execute")
def date():
print("Today is 2022-01-27.")
print("3层嵌套的decorator用法:")
date()
print("3层嵌套用法没有使用functools.wrap的date.__name__:",date.__name__)
# 1.date <======> log("execute")(date)
# 2.先执行log("execute"),返回decorator函数;
# 再调用返回的函数,参数是date函数,返回值最终是wrapper函数;
print("------------------------------------------------------------------")
# 把原始函数的__name__等属性复制到wrapper()函数,使用functools.wraps
# 在wrapper函数的前面添加@functools.wraps(func)
# 实例:
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print("Call %s():" % func.__name__)
return func(*args,**kw)
return wrapper
@log
def date():
print("今天是2022年1月27日.")
print("添加了functools处理的函数:",date.__name__)
date()
print("------------------------------------------------------------------")
# 带参数的decorator
import functools
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print("%s %s():" % (text,func.__name__))
return func(*args,**kw)
return wrapper
return decorator
@log("execute")
def moment():
print("现在是上午10点39分.")
print("3层嵌套添加functools处理的函数:",moment.__name__)
moment()
# 结果输出:
通过变量调用函数:
1min.
通过name属性,得到函数的名字为: time
变量通过name属性,可以得到函数的名字: time
------------------------------------------------------------------
添加了log的time函数:
Call time():
One min.
没有添加functoos.wrap的time.__name__: wrapper
------------------------------------------------------------------
3层嵌套的decorator用法:
execute date():
Today is 2022-01-27.
3层嵌套用法没有使用functools.wrap的date.__name__: wrapper
------------------------------------------------------------------
添加了functools处理的函数: date
Call date():
今天是2022年1月27日.
------------------------------------------------------------------
3层嵌套添加functools处理的函数: moment
execute moment():
现在是上午10点39分.
# 启动AGV控制前打印一些控制指令提示log
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args,**kw):
print("AGV按键控制")
print("----------W----------")
print("------A-------D------")
print("----------S----------\n")
print("Description:\n")
print("W按键实现前进")
print("A按键实现左转")
print("S按键实现后退")
print("D按键实现右转\n")
return func(*args,**kw)
return wrapper
@log
def control():
print("这是AGV控制程序测试.")
control()
# 结果输出:
AGV按键控制
----------W----------
------A-------D------
----------S----------
Description:
W按键实现前进
A按键实现左转
S按键实现后退
D按键实现右转
这是AGV控制程序测试.
2.偏函数
# 1.偏函数(Partial function)是functools模块提供的功能;
# 2.创建偏函数:functools.partial;
# 3.偏函数作用:把一个函数的某些参数固定住,即设置默认值,返回一个新的函数;
# 实例:
# int()函数可以把字符串转换为整数
numStr = "520"
numStr2 = "1010"
strToInt = int(numStr)
print("字符串原始内容为:",numStr)
print("字符串原始内容的类型为:",type(numStr))
print("字符串转换为整数为:",strToInt)
print("字符串转换后的类型为:",type(strToInt))
print("------------------------------------------")
# int()函数提供额外的base参数,默认值为10,如果传入base参数,实现做N进制的转换;
strTo2 = int(numStr2,base = 2)
strTo8 = int(numStr,base = 8)
strTo16 = int(numStr,base = 16)
print("'1010'按二进制转换:",strTo2)
print("'520'按八进制转换:",strTo8)
print("'520'按十六进制转换:",strTo16)
print("------------------------------------------")
# 实例:需要转换大量的二进制字符串,定义一个转换函数
def int2(x, base = 2):
return int(x, base)
# 测试:
print("1111按二进制转换:",int2("1111"))
print("10101010按二进制转换:",int2("10101010"))
print("------------------------------------------")
# 使用functools.partial创建偏函数
import functools
int2 = functools.partial(int, base = 2)
print("'1111'使用偏函数按二进制转换的结果:",int2("1111"))
print("'10101010'使用偏函数按二机制转换的结果:",int2("10101010"))
print("'10101010'使用偏函数按十进制转换的结果:",int2("10101010",base = 10))
# 结果输出:
字符串原始内容为: 520
字符串原始内容的类型为: <class 'str'>
字符串转换为整数为: 520
字符串转换后的类型为: <class 'int'>
------------------------------------------
'1010'按二进制转换: 10
'520'按八进制转换: 336
'520'按十六进制转换: 1312
------------------------------------------
1111按二进制转换: 15
10101010按二进制转换: 170
------------------------------------------
'1111'使用偏函数按二进制转换的结果: 15
'10101010'使用偏函数按二机制转换的结果: 170
'10101010'使用偏函数按十进制转换的结果: 10101010
import functools
strInput = input("请输入您要转换的数字:")
exchange = input("请输入您要按照什么进制进行转换(2、8、10、16):")
int2 = functools.partial(int, base = 2)
int8 = functools.partial(int, base = 8)
int10 = functools.partial(int, base = 10)
int16 = functools.partial(int, base = 16)
if (exchange == "2"):
print("按照二进制转换的结果为:",int2(strInput))
elif (exchange == "8"):
print("按照八进制转换的结果为:",int8(strInput))
elif (exchange == "10"):
print("按照十进制转换的结果为:",int10(strInput))
elif (exchange == "16"):
print("按照十六进制转换的结果为:",int16(strInput))
else:
print("输入不存在!")
print("再见!")
# 结果输出:
请输入您要转换的数字:10101010
请输入您要按照什么进制进行转换(2、8、10、16):2
按照二进制转换的结果为: 170
-----------------------------------------------
请输入您要转换的数字:1000
请输入您要按照什么进制进行转换(2、8、10、16):8
按照八进制转换的结果为: 512
-----------------------------------------------
请输入您要转换的数字:584520
请输入您要按照什么进制进行转换(2、8、10、16):10
按照十进制转换的结果为: 584520
-----------------------------------------------
请输入您要转换的数字:584520
请输入您要按照什么进制进行转换(2、8、10、16):16
按照十六进制转换的结果为: 5784864
-----------------------------------------------
请输入您要转换的数字:584520
请输入您要按照什么进制进行转换(2、8、10、16):9
输入不存在!
再见!