1. 预热知识

要理解python中的装饰器,就要明白在python中,函数是一种特殊类型的变量,可以作为参数传递给函数,也可以作为返回值返回。比如下面的代码,就是 str_1 作为参数传递给 str_2 ,然后再 str_2 中调用传入的函数。

def str_1():
print('good day') def str_2(func):
func() str_2(str_1)

再看下面的这段代码:

def str_2():

  def str_1():
print("abc") return str_1 str_2()()

这段代码在 str_2 内部定义的函数 str_1 作为一个变量返回,然后我们在调用 str_2时获取到返回之后,继续调用 str_1。

2. 了解 python 中的装饰器

2.1 装饰器的作用

装饰器本质是一个 python 函数,让其他函数在不需要任何代码变动的前提下增加额外的功能,其返回值也是一个函数对象。

2.2 功能实现过程

实例:

现在我们有以下一个函数:

def sum_1(a,b):
sum_1 = a + b
return sum_1

我们希望增加一个获得计算函数运行时间的功能,于是将代码修改如下:

import time

def sum_1(a,b):
time_1 = time.time()
sum_0 = a + b
print(time.time()-time_1)
return sum_0

如果我们有若干个函数需要相同的功能,所以你复制黏贴了代码如下:

import time

def sum_1(a,b):
time_1 = time.time()
sum_0 = a + b
print(time.time()-time_1)
return sum_0 def sum_2(a,b):
time_1 = time.time()
sum_0 = a + b
print(time.time()-time_1)
return sum_0

然而你抿了一口手中的咖啡,觉得这样有点low,于是你一拍脑袋,修改如下:

import time

def count_time(func,a,b):
    time_1 = time.time()
    sum_0 = func(a,b)
    print(time.time()-time_1)
    return sum_0 def sum_1(a,b):
    sum_0 = a + b
    return sum_0 def sum_2(a,b):
    sum_0 = a + b
    return sum_0 count_time(sum_1,1,2)
count_time(sum_2,3,4)

这看上去似乎有点模样了,然后我们还是没法直接运行 sum_1(a,b) 获得我们想要的结果,那么该如何不改变函数的调用方式,获得返回的结果呢?你再次抿了口咖啡,飞快地敲下如下的代码:

import time

def count_time(func):
def count(a,b):
time_1 = time.time()
sum_0 = func(a,b)
print(time.time()-time_1)
return sum_0
return count def sum_1(a,b):
sum_0 = a + b
return sum_0 def sum_2(a,b):
sum_0 = a + b
return sum_0 sum_1 = count_time(sum_1)
sum_2 = count_time(sum_2) sum_1(1,2)
sum_2(3,4)

emmmm,这样就舒服多了嘛,你的嘴角露出了一丝弧度,你不禁为自己的机智点了个赞,然后你不禁再次问自己,还能再简化下吗?

2.3 闪亮登场的 Decorator

你冥思苦想一番,用到了语法糖——装饰器。将上面的代码修改如下:

import time

def count_time(func):
def count(a,b):
time_1 = time.time()
sum_0 = func(a,b)
print(time.time()-time_1)
return sum_0
return count @count_time
def sum_1(a,b):
sum_0 = a + b
return sum_0 @count_time
def sum_2(a,b):
sum_0 = a + b
return sum_0 sum_1(1,2)
sum_2(3,4)

@符号是一个语法糖,将被包裹的函数作为一个变量传递给装饰函数/类,讲装饰函数/类返回的值替换原本的函数,即替换了以下过程:

sum_1 = count_time(sum_1)
sum_2 = count_time(sum_2)

到这里,你大概对 python 的装饰器有了个初步的了解了吧!

3. numba的基本使用

python是一种动态语言,如果能够让它静态一点,速度会好很多,于是有了 cpython。然后 cpython 还是有诸多不便。于是 numba 就成了一个强大而又方便的替代品。它对 for 循环有很好的效果,实例如下:

from numba import jit
from numpy import arange
import time @jit
def sum_1(arr):
M, N = arr.shape
result = 0.0
for i in range(M):
for j in range(N):
result += arr[i,j]
return result a = arange(9999999).reshape(3333333,3) start = time.time()
print(sum_1(a))
stop = time.time()
print(stop-start)

使用@jit 后的运行时间大约是0.06s,不使用@jit 的运行时间大约是3.2s,效果提高了50多倍。

小谈python装饰器及numba的基本使用的更多相关文章

  1. 浅谈Python装饰器

    一.概念 装饰器是Python语言中的高级语法.主要的功能是对一个函数.方法.或者类进行加工,作用是为已经存在的对象添加额外的功能,提升代码的可读性.装饰器是设计模式的一种,被用于有切面需求的场景,较 ...

  2. python装饰器通俗易懂的解释!

    1.python装饰器 刚刚接触python的装饰器,简直懵逼了,直接不懂什么意思啊有木有,自己都忘了走了多少遍Debug,查了多少遍资料,猜有点点开始明白了.总结了一下解释得比较好的,通俗易懂的来说 ...

  3. Python装饰器由浅入深

    装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...

  4. Python装饰器与面向切面编程

    今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...

  5. python装饰器方法

    前几天向几位新同事介绍项目,被问起了@login_required的实现,我说这是django框架提供的装饰器方法,验证用户是否登录,只要这样用就行了,因为自己不熟,并没有做过多解释. 今天查看dja ...

  6. 一篇关于Python装饰器的博文

    这是一篇关于python装饰器的博文 在学习python的过程中处处受阻,之前的学习中Python的装饰器学习了好几遍也没能真正的弄懂.这一次抓住视频猛啃了一波,就连python大佬讲解装饰器起来也需 ...

  7. python 装饰器 一篇就能讲清楚

    装饰器一直是我们学习python难以理解并且纠结的问题,想要弄明白装饰器,必须理解一下函数式编程概念,并且对python中函数调用语法中的特性有所了解,使用装饰器非常简单,但是写装饰器却很复杂.为了讲 ...

  8. Python装饰器模式学习总结

    装饰器模式,重点在于装饰.装饰的核心仍旧是被装饰对象. 类比于Java编程的时候的包装模式,是同样的道理.虽然概念上稍有不同但是原理上还是比较相近的.下面我就来谈一谈我对Python的装饰器的学习的一 ...

  9. Python 装饰器(Decorator)

    装饰器的语法为 @dec_name ,置于函数定义之前.如: import atexit @atexit.register def goodbye(): print('Goodbye!') print ...

随机推荐

  1. Spark Shuffle调优原理和最佳实践

    对性能消耗的原理详解 在分布式系统中,数据分布在不同的节点上,每一个节点计算一部份数据,如果不对各个节点上独立的部份进行汇聚的话,我们计算不到最终的结果.我们需要利用分布式来发挥Spark本身并行计算 ...

  2. 4.11 Routing -- Loading/Error Substates

    除了在上节中描述的技术,Ember路由器通过使用error和loading substates为自定义异步跳转提供强大而可重写的约定. 一.loading Substates 1. 在跳转过程中,Em ...

  3. BCB中换行 需要 \r\n

    例如: fprintf(fp,"\n");无换行效果 fprintf(fp,"\r\n");有换行效果

  4. king 选 太子

    king 选 太子 时间限制:3000 ms  |  内存限制:65535 KB 难度:1   描述 啊,从前有一个国家.此国兵强马壮,但是国王却身体不好.于是就想挑一位太子出来: 但是问题来了,国王 ...

  5. lua实现单例模式

    Singleton = {} function Singleton:new(o) o = o or {} setmetatable(o,self) self.__index = self return ...

  6. 72. Edit Distance(编辑距离 动态规划)

    Given two words word1 and word2, find the minimum number of operations required to convert word1 to  ...

  7. CTR预估中的贝叶斯平滑方法(一)原理及实验介绍

    1. 背景介绍 广告形式: 互联网广告可以分为以下三种: 1)展示广告(display ad) 2)搜索广告(sponsored search ad) 3)上下文广告(contextual ad)   ...

  8. python 中使用ConfigParser类修改配置文件

    配置文件的格式: [user] user_ip=127.0.0.1 user_name=testuser user_id=13 import ConfigParser conf = ConfigPar ...

  9. 前端学习笔记之HTTP协议

    阅读目录 一 HTTP协议简介 二 HTTP协议之请求Request 三 HTTP协议之响应Response 四 HTTP协议完整工作流程 五 HTTP协议关键性总结 六 自定义套接字分析HTTP协议 ...

  10. java实验五20145204

    java实验 Tcp传输 实验内容 运行代码一人服务器,一人客户端. 下载加解密代码,先编译运行代码,一人加密一人解密,适当修改代码. 集成代码,一人加密后通过TCP发送,加密使用AES或DES,AE ...