python中级第一课--元编程之给函数添加一个包装(小白piao分享)

什么是元编程?

        在很多书籍中只是浅显地为各位通过代码展示了元编程,多年的教学经验告诉我,得让你们得到一个实质性的总结之后再去看代码,效果会好很多:
        首先,作为一个程序兔子(秃子),必须要知道,‘一切重复的工作只会浪费大量时间’‘秃子一般很会偷懒’
        其次,任何时候,要去编写高度重复的代码时,都要找到一个更优雅的解决方案,这就是元编程,元编程指的是通过一系列方法简化代码量的过程,是一种编程方法,而非一个准确的理论概念

元编程的主要目的:

        创建函数和类,让它们来操作代码,或者说将代码托管给他们,让他们替我们完成大量的重复工作,如参数类型检查,打印函数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,谢谢各位。知识整理总结和博客创作多为不易,望勿抄袭,如要保存,请以转载发布,谢谢。坚持原创!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小白piao

创作不易,支持一下!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值