《流畅的Python》第三部分 把函数视作对象 【一等函数】【使用一等函数实现设计模式】【函数装饰器和闭包】
第三部分
第5章 一等函数
一等对象
- 在运行时创建
- 能赋值给变量或数据结构中的元素
- 能作为参数传递给函数
- 能作为函数的返回结果
在Python中,所有函数都是一等对象
函数是对象
函数本身是 function 类的实例。
高阶函数
- 接受函数为参数,或者把函数作为结果返回的函数
- 内置高阶函数:map, filter, reduce
- 列表推导式或生成器推导式同时具有 map 和 filter 两个函数的功能
类的调用
- 调用类的过程:运行类的 __ new __ 方法创建一个实例,然后运行 __ init __ 方法,初始化实例,最后返回实例给调用方
- 如果类定义了 __ call __ 方法,那么类的实例可以作为函数调用*
- 使用内置函数 callable() 判断对象是否可调用
? yield 生成器函数
函数参数
可以通过 inspect.signature( func ) 查看函数的参数信息
def func(a, b, c, *var, d, **kw):
'''
a, b, c: 位置参数,关键字参数
var: 可变参数
d: 仅限关键字参数
kw: 可变关键字参数
'''
print("a=",a)
print("b=",b)
print("c=",c)
print("var=",var)
print("d=",d)
print("kw=",kw)
func('a','b','c','var1','var2',d='d',kw1='kw1',kw2='kw2')
# a= a
# b= b
# c= c
# var= ('var1', 'var2')
# d= d
# kw= {'kw1': 'kw1', 'kw2': 'kw2'}
- 位置参数(POSITIONAL_OR_KEYWORD)
- 参数定义时,前面的 a, b, c 参数可以直接传入值,并按位置接收
- def fun(a,b,c)
- fun(1,2,3)
- a,b,c = 1,2,3
- 参数定义时,前面的 a, b, c 参数可以直接传入值,并按位置接收
- 关键字参数
- 参数传入的时候可以自定义接受的关键字
- def fun(a,b,c)
- fun(c=1,a=2,b=3)
- a,b,c = 2,3,1
- 参数传入的时候可以自定义接受的关键字
- 可变参数(VAR_POSITIONAL)
- 未定义且不带关键字的参数传入,使用可变参数接受形成元组
- def fun(*var)
- fun(1,2,3)
- var = (1,2,3)
- 未定义且不带关键字的参数传入,使用可变参数接受形成元组
- 仅限关键字参数(KEYWORD_ONLY)
- 可变参数后面的参数传入,只能带上关键字传入
- def fun(*var,a)
- fun(1,2,3,a=4)
- var,a = (1,2,3),4
- 可变参数后面的参数传入,只能带上关键字传入
- 可变关键字参数(VAR_KEYWORD)
- 未定义的关键字参数传入,使用可变关键字参数接受形成字典
- def fun(a,b,c,**kw)
- fun(a=1,b=2,c=3,d=4,e=5)
- a,b,c,kw = 1,2,3,{'d':4,'c':5}
- 未定义的关键字参数传入,使用可变关键字参数接受形成字典
参数信息保存在 __ code __. 通过 inspect.signature( func ).parameters.items() 可以看到函数的各项参数名称、类型、默认值
默认值保存在 __ defualt __. 通过 inspect.signature( func ).bind( param_dict ) 可以设定或改变参数的默认值
函数注解
def func(a:float, b:'int > 0' =80) -> str
pass
Python 对注解所做的唯一的事情是,把它们存储在函数的 __ annotations __ 属性里。仅此而已,Python 不做检查、不做强制、 不做验证,什么操作都不做。
函数式编程
- operator 模块
- mul(a,b) 代替 lambda a,b: a*b
- itemgetter(*idxs) 通过一系列特定位置提取序列中的相应元素
sel = operator.itemgetter(1, 3)
print(sel(range(1,10,2)))
# (3,7)
- attrgetter(*param) 通过一系列属性名称提取对象相应的属性值
- functools 模块
- reduce(func, sec) 在 sec 元素上进行 func 参数,与 filter和map 不同
#阶乘
def factorial(n):
return functools.reduce(lambda a,b: a*b, range(1,n+1))
- reduce(func, sec) 在 sec 元素上进行 func 参数,与 filter和map 不同
第6章 使用一等函数实现设计模式
将外部函数作为参数传入对象的内部,以达到对象内部使用外部函数的目的
def list_operater(l,func):
for i in l:
func(i,end=' ')
list_operater(range(5),print)
# 0 1 2 3 4
promos = [operator.add, operator.mul, operator.sub]
print(max(functools.reduce(promo, range(3,-2,-1)) for promo in promos))
# 5
第7章 函数装饰器和闭包
装饰器
- 装饰器是一个 “装饰” 函数的函数。
- 装饰器在被装饰的函数定义之后立即进行运行
#----------- 1 ----------
@decorate
def target():
print("target")
#----------- 2 ----------
def target():
print("target")
target = decorate(target)
#----------上面两个等同-------------
def decorate(func):
def inner():
print("inner")
return inner
target()
# 输出 inner
def dec(func):
print("dec")
return func
@dec
def func():
print("func")
func()
# dec
# func
变量作用域
- 在函数体内部有赋值的操作的变量默认为局部变量
- global 适用于函数内部修改全局变量的值
- nonlocal 适用于嵌套函数中内部函数修改外部变量的值
a = 6
def f2():
print(a)
def f3():
print(a) # 这一行报错 需要定义global或nonlocal
a = 5
f2()
f3()
闭包
- 和使用匿名函数的方式一样,函数内部定义函数,且引用了自由变量。
def fun():
times = 0
def add(t):
nonlocal times
times += t
return times
return add
cli = fun()
cli_1 = fun()
print(cli(10)) # 10
print(cli(20)) # 30
print(cli_1(7)) # 7
print(cli(10)) # 40
print(cli_1(9)) # 16
标准库中的装饰器
- @functools.wraps( func )
- 将 func 的属性复制到被装饰的函数中
- @functools.lru_cache(maxsize=128, typed=False)
- 备忘,将耗时的函数结果保存起来,避免传入相同参数时重复计算
- maxsize 参数指定存储多少个调用结果,旧的丢掉。(应设置为2的幂值)
- typed 当True时,不同参数类型得到的结果分开存储
单分派泛函数
- 根据第一个参数的类型,以不同的方式执行相同操作的一组函数
- @functools.singleispatch
@functools.singledispatch
def judgetype(obj):
return 'obj'
#装饰器 [basefuncion].register([type]) 的形式
#函数名称无所谓了,用 _ 简单点
@judgetype.register(str)
def _(text):
return 'str: '+repr(text)
@judgetype.register(numbers.Integral)
def _(n):
return 'int: '+repr(n)
@judgetype.register(tuple)
def _(t):
return 'tuple: '+repr(t)
@judgetype.register(abc.MutableSequence)
def _(seq):
return 'seq: '+repr(seq)
print(judgetype(100))
print(judgetype('100'))
print(judgetype((100)))
print(judgetype([100]))
# int: 100
# str: '100'
# int: 100
# seq: [100]
叠放装饰器
- 将 @d1 和 @d2 顺序应用到 f 函数上,作用相当于 f = d1(d2(f))
参数化装饰器(工厂函数)
- def deco(a)
- @deco(a=True) # 以函数的形式调用装饰器
《流畅的Python》第三部分 把函数视作对象 【一等函数】【使用一等函数实现设计模式】【函数装饰器和闭包】的更多相关文章
- 流畅的python第七章函数装饰器和闭包学习记录
本章讨论的话题 python如何计算装饰器句法 python如何判断变量是不是局部的(通过函数内部是否给变量赋值过来判断是否是局部变量) 闭包存在的原因和工作原理(闭包是一种函数,它会保留定义函数时存 ...
- python设计模式之装饰器详解(三)
python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...
- Python 函数装饰器和闭包
装饰器基础知识 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数). 装饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个函数或可调用对象. p.p1 { margin: 0.0px ...
- python函数下篇装饰器和闭包,外加作用域
装饰器和闭包的基础概念 装饰器是一种设计模式能实现代码重用,经常用于查日志,性能测试,事务处理等,抽离函数大量不必的功能. 装饰器:1.装饰器本身是一个函数,用于装饰其它函数:2.功能:增强被装饰函数 ...
- Python——day14 三目运算、推导式、递归、匿名、内置函数
一.三目(元)运算符 定义:就是 if...else...语法糖前提:简化if...else...结构,且两个分支有且只有一条语句注:三元运算符的结果不一定要与条件直接性关系 cmd = input ...
- python进阶(三)~~~装饰器和闭包
一.闭包 满足条件: 1. 函数内嵌套一个函数: 2.外层函数的返回值是内层函数的函数名: 3.内层嵌套函数对外部作用域有一个非全局变量的引用: def func(): print("=== ...
- 『流畅的Python』第9章笔记_对象
一.Python风格 以一个二元素向量对象为例 import math from array import array class Vector2d: typecode = 'd' def __ini ...
- Fluent_Python_Part3函数即对象,05-1class-func,一等函数,函数即对象
一等函数 一等函数即将函数看作一等对象.一等对象满足一下条件: 在运行时创建 能赋值给变量或数据结构中的元素 能作为参数传给函数 能作为函数的返回结果 1. 一等函数 例子1. 证明function是 ...
- python基础语法16 面向对象3 组合,封装,访问限制机制,内置装饰器property
组合: 夺命三问: 1.什么是组合? 组合指的是一个对象中,包含另一个或多个对象. 2.为什么要用组合? 减少代码的冗余. 3.如何使用组合? 耦合度: 耦: 莲藕 ---> 藕断丝连 - 耦合 ...
随机推荐
- Vue企业级优雅实战03-准备工作04-全局设置
本文包括如下几个部分: 初始化环境变量文件 JS 配置文件初始化:如是否开启 Mock 数据.加载本地菜单.URL 请求路径等: 国际化文件初始化:初始化国际化文件的结构: 整合 Element UI ...
- P1082 同余方程(拓展欧几里德)
题目描述 求关于xx的同余方程 a x \equiv 1 \pmod {b}ax≡1(modb) 的最小正整数解. 输入输出格式 输入格式: 一行,包含两个正整数 a,ba,b,用一个空格隔开. 输出 ...
- .Net在Windows上使用Jenkins做CI/CD的那些事
背景 最近入职了一家新公司,公司各个方面都让我非常的满意,我也怀着紧张与兴奋的心情入职后,在第一天接到了领导给我的第一个任务——把整个项目的依赖引用重新整理并实施项目的CI/CD. 本篇的重点主要分享 ...
- 在微信公众号"码海"里学了一招:在update语句里使用case when 以避免多次更新导致的数据异常.
需求:将emp表中工资大于一万的降到9成,工资少于一万的乘以1.2. 难点:如果分成两句update执行,在10000附近的值可能会执行两次. 钥匙:在update语句里采用case when,使更新 ...
- 使用dbUnit的 IDataSet 因乱序造成assert失败而采取的措施
本例源码下载:https://files.cnblogs.com/files/xiandedanteng/dbUnitTest20200211.zip 在做IDataSet比较时,特殊情况下会有期盼的 ...
- 开发一个渐进式Web应用程序(PWA)前都需要了解什么?
转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. 原文出处:https://dzone.com/articles/how-to-build-a-progres ...
- C#开发PACS医学影像处理系统(十三):绘图处理之病灶测量
接上一篇文章,当我们可以绘制图形标记后,就可以在此操作类上面进行扩展, 比如测量类工具,目前整理出的常用绘图和测量功能如下: 测量工具类:(图形标记类请参考本系列文章:绘图处理之图形标记) 功能 说明 ...
- IdentityServer4与API单项目整合(net core 3.X)
一.创建一个空的api项目 添加identityserver4的nuget包 配置config文件 public static IEnumerable<IdentityResource> ...
- 关于浏览器访问iLO报错ERR_SSL_BAD_RECORD_MAC_ALERT
公司有几台HP DL380 G7服务器,ilo版本是ilo3(Integrated Lights-Out 3),ilo口配置好后,无法正常打开ilo页面 ping ilo口是通的,并且telnet 8 ...
- 你还不会ES的CUD吗?
近端时间在搬砖过程中对es进行了操作,但是对es查询文档不熟悉,所以这两周都在研究es,简略看了<Elasticsearch权威指南>,摸摸鱼又是一天. es是一款基于Lucene的实时分 ...