什么是元编程?
在很多书籍中只是浅显地为各位通过代码展示了元编程,多年的教学经验告诉我,得让你们得到一个实质性的总结之后再去看代码,效果会好很多:
首先,作为一个程序兔子(秃子),必须要知道,‘一切重复的工作只会浪费大量时间’ 和 ‘秃子一般很会偷懒’
其次,任何时候,要去编写高度重复的代码时,都要找到一个更优雅的解决方案,这就是元编程,元编程指的是通过一系列方法简化代码量的过程,是一种编程方法,而非一个准确的理论概念
元编程的主要目的:
创建函数和类,让它们来操作代码,或者说将代码托管给他们,让他们替我们完成大量的重复工作,如参数类型检查,打印函数log等。。。
元编程的主要特征:
包括:装饰器,类装饰器,元类,或者其他有用的主题–对象签名等。
从给函数添加包装开始:
简单的小例子:
import time
from functools import wraps
def total_runtime(func):
@wraps(func)
def wapper(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print('%s runtime is '%(func.__name__),end - start,'s')
return result
return wapper
@total_runtime
def f__k(num):
for x in range(1,num+1):
print('i want f**k you %d times'%(x))
f__k(10000)
'''
...
i want f**k you 9997 times
i want f**k you 9998 times
i want f**k you 9999 times
i want f**k you 10000 times
f__k runtime is 0.10893654823303223 s
'''
以上这个小例子就位我们展示了,它会为所有函数都添加执行时间这个特点,wrapper函数提供了*args和**kwargs是为了方便接受所有类型的参数而设计的,这也是非常常见的一种设计手段。
以上这些代码和如下功能是一样的,但是如果重复去写这些代码真的非常烦,有同学说,老师我有复制粘贴(头给你打歪):
def f__k(num):
...
f__k = total_runtime(f__k)
有一个细节,这里的@wrap就是一个可以保留函数元数据的装饰器。接下来,如何保留函数的元数据成了一个关键点:
切记!在设计所有的函数装饰器时,记得带上@wrap,为什么,因为该装饰器的内部,帮我们保留了函数的基本数据(元数据)例如:函数名、docstring(文本字符串)、函数参数签名等。。。
import time
from functools import wraps
def total_runtime(func):
@wraps(func)
def wapper(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print('%s runtime is '%(func.__name__),end - start,'s')
return result
return wapper
@total_runtime
def f__k(num:int):
'''
:param num: int
:return: None
'''
while num>0:
num -= 1
f__k(10000)
#尝试打印如下信息:
print(f__k.__doc__)
print(f__k.__name__)
print(f__k.__annotations__)
'''
:param num: int
:return: None
f__k
{'num': <class 'int'>}
Process finished with exit code 0
'''
#但是当我们省略@wrap之后:
import time
from functools import wraps
def total_runtime(func):
#@wraps(func)
def wapper(*args,**kwargs):
start = time.time()
result = func(*args,**kwargs)
end = time.time()
print('%s runtime is '%(func.__name__),end - start,'s')
return result
return wapper
@total_runtime
def f__k(num:int):
'''
:param num: int
:return: None
'''
while num>0:
num -= 1
f__k(10000)
print(f__k.__doc__)
print(f__k.__name__)
print(f__k.__annotations__)
'''
None
wapper
{}
Process finished with exit code 0
'''
#这会导致函数元数据发生了丢失,区别一目了然。
以上为本节基础内容,后续内容持续更新,想要学习更多的python基础知识,就请关注江湖小白piao,谢谢各位。知识整理总结和博客创作多为不易,望勿抄袭,如要保存,请以转载发布,谢谢。坚持原创!!!