Python闭包函数和装饰器

2018年7月2日笔记

7.Python函数对象和闭包

1.函数对象

函数是对象,可以给函数增加属性

def funcF(x,y,z):
    print(x,y,z)
funcF(1,2,3)
funcF.abc = "hello python"
print(funcF.abc

上面一段代码的运行结果如下:

1 2 3 hello python

2.函数闭包

1.概念:在一个外函数中定义了一个内函数,内函数运用了外函数的临时变量,并且外函数的返回值是内函数的引用 示例代码:演示函数嵌套和闭包。

def outer(a):
    b = 10
    def inner():
        print(a+b)
    return inner

demo = outer(5)
demo()

上面一段代码的运行结果如下:

15

8.Python装饰器

1.定义

装饰器实质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。他经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

2.场景

2.1 通过变量也能调用该函数

def hello():
    print("我是最初的hello函数")
#函数也是一个对象,而且函数对象可以赋值给变量
f = hello
f()

上面一段代码的运行结果如下:

我是最初的hello函数

2.2 场景 函数对象有一个name属性,可以获取函数的名字

def hello():
    print("我是最初的hello函数")

#获取函数的名字
print(hello.__name__)

上面一段代码的运行结果如下:

hello

2.3 假设增加hello()函数的功能,而完全不改变原来的代码

def outer(func):
    def inner(*args,**kwargs):
        print("我是%s()函数" %func.__name__)
        return func(*args,**kwargs)
    return inner

@outer
def hello():
    print("我是最初的hello函数")
hello()

上面一段代码的运行结果如下:

我是hello()函数 我是最初的hello函数

2.4 支持多个装饰器

import time

def deco1(func):
    print("deco1 decorated")
    def wrapper(*args, **kwargs):
        print("this is deco1")
        startTime = time.time()
        func(*args, **kwargs)
        endTime = time.time()
        ms = (endTime - startTime) * 1000
        print("time is %s ms" % ms)
        print("deco1 end here")
    return wrapper

def deco2(func):
    print("deco2 decorated")
    def wrapper(*args, **kwargs):
        print("this is deco2")
        func(*args, **kwargs)
        print("deco2 end here")
    return wrapper

@deco1
@deco2
def func(a, b):
    print("hello, here is func for add:")
    time.sleep(1)
    print("result is %d" % (a + b))

func(3, 4)

上面一段代码的运行结果如下:

deco2 decorated deco1 decorated this is deco1 this is deco2 hello, here is func for add: result is 7 deco2 end here time is 1000.9815692901611 ms deco1 end here

多个装饰器使用的调用顺序:

def one(func):
    print('----1----')
    def two():
        print('----2----')
        func()
        print('----3----')
    return two

def a(func):
    print('----a----')
    def b():
        print('----b----')
        func()
        print('----c----')
    return b

@one
@a
def demo():
    print('----demo----')

demo()

上面一段代码的运行顺序如下:

----a---- ----1---- ----2---- ----b---- ----demo---- ----c---- ----3----

图片.png-18.5kB

如上图所示,红色箭头标记“1”和“3”处越靠近函数的装饰器先被执行,红色箭头标记“2”处越远离函数的装饰器先被执行。

练习

1.定义一个函数,需求:去除列表中重复的元素.

def dropDuplicates(lt):
    new_list = []
    for i in lt:
        if i not in new_list:
            new_list.append(i)
    return new_list
##第二种方法一行代码解决
def dropDuplicates2(lt):
    return list(set(lt))

2.定义一个函数,需求:合并两个列表

def concatList(lt1,lt2):
    return lt1 + lt2

def concatList2(lt1,lt2):
    lt1.extend(lt2)
    return lt1

def concatList3(lt1,lt2):
    for i in lt2:
        lt1.append(i)
    return lt1

3.定义函数,需求:判断三个数中的最大值

def my_max(*args):
    return max(*args)

def my_max1(*args):
    max_number = args[0]
    for i in args:
        if i > max_number:
            max_number = i
    return max_number

4.定义一个函数,需求:实现斐波那契数列

def fibonacci(length):
    if length < 1:
        print("参数应该为正整数")
    if length == 1:
        return [1]
    elif length == 2:
        return [1,1]
    lt = [1,1]
    for i in range(2,length):
        lt.append(lt[i-1] + lt[i-2])
    return lt

5.将下列字符串变成字典

t = "k:1|k1:2|k2:3|k3:4"
result = {x:y for x,y in [k.split(':') for k in t.split('|')]}
print(result)

字符串函数

s = 'i love You so much'

print(s.ljust(22, '*'))
print(s.rjust(22, '2'))
print(s.center(22, '*'))
print(s.zfill(22))
print(s.replace('u', '1', 1))
print(s.split(' '))
print(s.upper())
print(s.lower())
print(s.capitalize())
print(s.title())
print(s.swapcase())
print(s.count('o'))
print(s.startswith('i'))
print(s.endswith('!'))
print(s.isalnum())
print(s.isalpha())
print(s.islower())
print(s.isupper())
print(s.istitle())

上面一段代码的运行结果如下:

i love You so much****
2222i love You so much
**i love You so much**
0000i love You so much
i love Yo1 so much
['i', 'love', 'You', 'so', 'much']
I LOVE YOU SO MUCH
i love you so much
I love you so much
I Love You So Much
I LOVE yOU SO MUCH
3
True
False
False
False
False
False
False

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coder修行路

Java基础(三)面向对象(下)

成员常量:public static final 成员函数:public abstract

1030
来自专栏青青天空树

C语言中把数字转换为字符串 【转】

在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者...

4.3K5
来自专栏Python自动化测试

python装饰器的学习

在python中,装饰器是一种增加函数功能的简单方法,利用装饰器功能可以很快的给不同的函数插入相同的功能。

1273
来自专栏小樱的经验随笔

【正则表达式学习笔记之一】简单认识正则表达式

一、引言   正则表达式是什么东东?   在编写处理字符串的程序或网页时,经常会有查找符合某些复杂规则的字符串的需要。正则表达式就是用于描述这些规则的工具。换句...

2133
来自专栏散尽浮华

Python内置函数

内置函数之一:lambda表达式 前面知识回顾: 三目运算: #普通条件语句 1: if 1 == 1: 2: name ='曹小贱' 3:...

2165
来自专栏技术小黑屋

Java中的字符串常量池

Java中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String...

1872
来自专栏老九学堂

干货 | Java 中不得不知的异常和处理详解

简介 程序运行时,发生的不被期望的事件,它阻止了程序按照程序员的预期正常执行,这就是异常。异常发生时,是任程序自生自灭,立刻退出终止,还是输出错误给用户?或者用...

4037
来自专栏Linyb极客之路

JVM 方法内联

调用某个函数实际上将程序执行顺序转移到该函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。

2114
来自专栏九彩拼盘的叨叨叨

学习纲要:JavaScript 数据类型

721
来自专栏大前端_Web

javascript语言精粹(蝴蝶书)-笔记

版权声明:本文为吴孔云博客原创文章,转载请注明出处并带上链接,谢谢。 https://blog.csdn.net/wkyseo/articl...

3643

扫码关注云+社区

领取腾讯云代金券