装饰器前奏:

一.定义:

  1.装饰器本质是函数,语法都是用def去定义的

  (函数的目的:他需要完成特定的功能)

  2.装饰器的功能:就是装饰其他函数(就是为其他函数添加附加功能)

二.原则:

  1. 不能修改被装饰的函数的源代码

  2. 不能修改被修饰的函数的调用方式

三. 实现装饰器知识储备:

  1.函数即“变量”  (先定义,再调用)

  2.高阶函数

  3.嵌套函数

  4.匿名函数   样式 (calc = lambde x:x*3 )

高阶函数 + 嵌套函数 =》 装饰器

1. 函数即“变量”

  (1). python的内存机制

1
2
3
4
5
#变量
= 1
#函数
def test():
    pass

     以上一个变量一个函数在内存中的表现形式如下图:

     在python解释器中,有一个概念叫做引用基数,那什么叫引用基数呐,就是比方说,x=1,它会先在内存当中把1这个值试试在在的存放下来,这个x其实就是1的门牌号,也是对1的一次引用。python什么时候把这个1这个屋子清空呐?它会等到1所对应的门牌号都没有了,就会把1这里面的东西给清掉,这个也是python的内存回收机制,就是靠这种方式回收的。

  (2). del清理

    那我们用什么清理呐?用del去清理门牌号,就是对1的值引用的变量,del  x就表示清理掉1对应的x的门牌号。如果x没有被del,则x永远不还被删除,除非程序结束了,不然永远不会被删除。del删除的不是1,只是把门牌号x删除了,只是定期刷新时,发现1没有被其他门牌号引用了,才会被清掉。

  (3). 函数在内存的表现形式

  我们先通过四个例子来解释一下:

  ①bar函数没有定义

1
2
3
4
5
6
7
8
9
10
11
12
 
#bar函数没有定义
def foo():
    print("in the foo")
    bar()
 
foo()
 
#输出
in the foo

NameError: name 'bar' is not defined

 

  ②bar函数在foo函数之后定义

1
2
3
4
5
6
7
8
9
10
11
12
13
#bar函数在foo函数之后定义
def foo():
    print("in the foo")
    bar()
 
def bar():
    print("in the bar")
 
foo()
 
#输出
in the foo
in the bar

 

 ③bar函数是在foo函数之前定义

1
2
3
4
5
6
7
8
9
10
11
12
13
# bar函数是在foo函数之前定义
def bar():
    print("in the bar")
 
def foo():
    print("in the foo")
    bar()
 
foo()
 
#输出
in the foo
in the bar

  显然,两种写法效果是一样的,那我们来看看第四种情况。

  ④bar函数在foo函数调用之后声明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# bar函数在foo函数调用之后声明
def foo():
    print("in the foo")
    bar()
 
foo()
 
def bar():
    print("in the bar")
 
#输出
Traceback (most recent call last):
in the foo
  File "D:/PycharmProjects/pyhomework/day4/装饰器/函数即变量.py", line 31in <module>
    foo()
  File "D:/PycharmProjects/pyhomework/day4/装饰器/函数即变量.py", line 29in foo
    bar()
NameError: name 'bar' is not defined  #bar函数没有定义

2.高阶函数

满足下面条件之一就可以称为高阶函数:

  a.把一个函数名当做实参传给另一个函数

  b.返回值中包含函数名(调用函数体)

1、把一个函数名当做实参传给另外一个函数

作用:在不修改被装饰函数源代码的情况下为其添加功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def bar():
    time.sleep(3)
    print("in the bar")
 
def test1(func):
    print(func)
    start_time = time.time()
    func()   #run bar
    stop_time = time.time()
    print("the func run the is %s"%(stop_time-start_time))
#没有修改bar的代码
test1(bar)  #把bar函数名当做实参传到test1中
 
#输出
<function bar at 0x0000000000A7D378>  #bar函数的内存地址
in the bar
the func run the is 2.9912972450256348

2、返回值中包括函数名

作用:不修改函数调用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import  time
 
def bar():
    time.sleep(3)
    print("in the bar")
 
def test2(func):
    print(func)
    return func   #返回函数的内存地址
 
#调用test2函数
bar = test2(bar) 
bar()  #没有bar函数改变调用方式
 
#输出
<function bar at 0x0000000000B6D378>  #打印bar函数的内存地址
in the bar
 

小白的Python之路 day4 装饰器前奏的更多相关文章

  1. 小白的Python之路 day4 装饰器高潮

    首先装饰器实现的条件: 高阶函数+嵌套函数 =>装饰器 1.首先,我们先定义一个高级函数,去装饰test1函数,得不到我们想要的操作方式 import time #定义高阶函数 def deco ...

  2. python之路之装饰器

    一 装饰器进化之路1) import time def index(): start_time=time.time() time.sleep() print('welcome to index wor ...

  3. [Python之路] 使用装饰器给Web框架添加路由功能(静态、动态、伪静态URL)

    一.观察以下代码 以下来自 Python实现简易HTTP服务器与MINI WEB框架(利用WSGI实现服务器与框架解耦) 中的mini_frame最后版本的代码: import time def in ...

  4. 小白的Python之路 day4 生成器

    一.列表生成式  看下面例子: 列表生成式的作用:主要是让代码更简洁(还有装X的效果) 二.生成器 通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包 ...

  5. 小白的Python之路 day4 迭代器

    迭代器 学习前,我们回想一下可以直接作用于for循环的数据类型有以下几种: 1.集合数据类型,如list.tuple.dict.set.str等: 2.是generator,包括生成器和带yield的 ...

  6. 小白的Python之路 day4 json and pickle数据标准序列化

    一.简述 我们在写入文件中的数据,只能是字符串或者二进制,但是要传入文件的数据不一定全是字符串或者二进制,那还要进行繁琐的转换,然后再读取的时候,还要再转回去,显得很麻烦,今天就来学习标准的序列化:j ...

  7. 小白的Python之路 day4 软件目录结构规范

    软件目录结构规范 为什么要设计好目录结构? "设计项目目录结构",就和"代码编码风格"一样,属于个人风格问题.对于这种风格上的规范,一直都存在两种态度: 一类同 ...

  8. 小白的Python之路 day4 不同目录间进行模块调用(绝对路径和相对路径)

    一.常用模块调用函数功能解释 1.__file__ 功能:返回自身文件的相对路径 你从pycharm的执行结果可以看出,在pycharm执行atm.py文件时,是从绝对路径下去执行的,而你从cmd下去 ...

  9. 小白的Python之路 day4 生成器并行运算

    一.概述 我们已经明白生成器内部的结构,其实就是通过像函数这样的东西实现的! 多线程和单线程:简单来说多线程就是并行运算,单线程就是串行运算 二.生成器执行原理 第一步:生成一个生成器  第二步:执行 ...

随机推荐

  1. 分享一篇vue项目规范

    最近 Vue 用的比较多,而且因为公司里有实习生,当几个人写一个项目的时候,会出现很多问题,最麻烦的就是规范不统一,之前我有一篇文章是说, vue 是比较有规范的一种框架了,但是也会出现很多问题,所以 ...

  2. Java数据结构和算法(一)——简介

    本系列博客我们将学习数据结构和算法,为什么要学习数据结构和算法,这里我举个简单的例子. 编程好比是一辆汽车,而数据结构和算法是汽车内部的变速箱.一个开车的人不懂变速箱的原理也是能开车的,同理一个不懂数 ...

  3. Vue.js简单的应用

    1:一个简单实现 下面代码部分: <body> <div id="myDiv1"> {{userName}} </div> </body& ...

  4. 学习MySQL(上)

    具体实例 1.PHP 服务器组件 对于初学者建议使用集成的服务器组件,它已经包含了 PHP.Apache.Mysql 等服务,免去了开发人员将时间花费在繁琐的配置环境过程. Window 系统可以使用 ...

  5. 我的第一个python web开发框架(17)——产品管理

    这是后台管理系统最后一个功能,产品管理,它的接口与页面功能与上一章差不多. 获取产品列表接口 @get('/api/product/') def callback(): ""&qu ...

  6. git学习——Github关联(2)

    一.参考学习链接 1.重点看Github与Git的关联. http://www.cnblogs.com/schaepher/p/5561193.html#github 2.git的全面详细介绍. ht ...

  7. 自己动手编写IOC框架(四)

    终于到了激动人心的时刻了,首先感谢小伙伴们的阅读,如果能多点评论,多点探讨就更好了,没有交流让我觉得我写的东西只有标题有点价值,内容只是在浪费大家的时间.为了泪滴下周能写下一个框架orm,请小伙伴们能 ...

  8. 51Nod 1284 2 3 5 7的倍数 容斥原理

    1284 2 3 5 7的倍数基准时间限制:1 秒 空间限制:131072 KB 分值: 5 难度:1级算法题 收藏 关注给出一个数N,求1至N中,有多少个数不是2 3 5 7的倍数. 例如N = 1 ...

  9. js 数组去重复的方法

    数组去重复是js中常用的方法,归纳了四种如下: 1. for + indexOf  去重复 var arr = [3,5,5,4,1,1,2,3,7,2,5]; var target = []; fo ...

  10. MongoDB之建立Windows和本地虚拟机的双向连接

    本文主要分享如何将MongoDB数据库在Windows系统和本地虚拟机系统建立双向连接,我们将借助MongoDB的可视化工具Robomongo来实现.首先,应该确保你的Windows系统和本地虚拟机系 ...