第三部分

第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
  • 关键字参数
    • 参数传入的时候可以自定义接受的关键字

      • 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))

第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》第三部分 把函数视作对象 【一等函数】【使用一等函数实现设计模式】【函数装饰器和闭包】的更多相关文章

  1. 流畅的python第七章函数装饰器和闭包学习记录

    本章讨论的话题 python如何计算装饰器句法 python如何判断变量是不是局部的(通过函数内部是否给变量赋值过来判断是否是局部变量) 闭包存在的原因和工作原理(闭包是一种函数,它会保留定义函数时存 ...

  2. python设计模式之装饰器详解(三)

    python的装饰器使用是python语言一个非常重要的部分,装饰器是程序设计模式中装饰模式的具体化,python提供了特殊的语法糖可以非常方便的实现装饰模式. 系列文章 python设计模式之单例模 ...

  3. Python 函数装饰器和闭包

    装饰器基础知识 装饰器是可调用的对象,其参数是另一个函数(被装饰的函数). 装饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个函数或可调用对象. p.p1 { margin: 0.0px ...

  4. python函数下篇装饰器和闭包,外加作用域

    装饰器和闭包的基础概念 装饰器是一种设计模式能实现代码重用,经常用于查日志,性能测试,事务处理等,抽离函数大量不必的功能. 装饰器:1.装饰器本身是一个函数,用于装饰其它函数:2.功能:增强被装饰函数 ...

  5. Python——day14 三目运算、推导式、递归、匿名、内置函数

    一.三目(元)运算符 定义:就是 if...else...语法糖前提:简化if...else...结构,且两个分支有且只有一条语句注:三元运算符的结果不一定要与条件直接性关系​ cmd = input ...

  6. python进阶(三)~~~装饰器和闭包

    一.闭包 满足条件: 1. 函数内嵌套一个函数: 2.外层函数的返回值是内层函数的函数名: 3.内层嵌套函数对外部作用域有一个非全局变量的引用: def func(): print("=== ...

  7. 『流畅的Python』第9章笔记_对象

    一.Python风格 以一个二元素向量对象为例 import math from array import array class Vector2d: typecode = 'd' def __ini ...

  8. Fluent_Python_Part3函数即对象,05-1class-func,一等函数,函数即对象

    一等函数 一等函数即将函数看作一等对象.一等对象满足一下条件: 在运行时创建 能赋值给变量或数据结构中的元素 能作为参数传给函数 能作为函数的返回结果 1. 一等函数 例子1. 证明function是 ...

  9. python基础语法16 面向对象3 组合,封装,访问限制机制,内置装饰器property

    组合: 夺命三问: 1.什么是组合? 组合指的是一个对象中,包含另一个或多个对象. 2.为什么要用组合? 减少代码的冗余. 3.如何使用组合? 耦合度: 耦: 莲藕 ---> 藕断丝连 - 耦合 ...

随机推荐

  1. String painter (区间dp)

    There are two strings A and B with equal length. Both strings are made up of lower case letters. Now ...

  2. 数据库行转列的sql语句

    问题描述 假设有张学生成绩表(CJ)如下Name Subject Result张三 语文 80张三 数学 90张三 物理 85李四 语文 85李四 数学 92李四 物理 82 现在 想写 sql 语句 ...

  3. C++STL中vector的初始化

    vector的初始化有很多方式,在N维初始化时还会一些容易出现错误的地方.下面进行总结 以下的总结均以int作为模板参数 一维vector的初始化 vector的构造函数通常来说有五种,如下: vec ...

  4. 使用grep命令查找文件中符合”.stg.“行

    某目录下有个test.txt,内容如下: www.stg.comwwstgcom 如果我这样去查找: $ grep '.stg.' test.txtwww.stg.comwwstgcom 发现第二个匹 ...

  5. 使用Built-in formatting来创建log字符串

    在一次哦测试中,sonar-qube总是报Use the built-in formatting to contruct this argument, 在网上查了一下,原来它是推荐这样做: log.i ...

  6. 电子邮箱有哪些隐藏技能,读懂了效率提升N倍!

    很多人将邮箱作为常见的通讯工具,然而,大部分职场人只了解其五分之一的功能.电子邮箱还有很多隐藏技能,身为商务精英的你,必须往下看看哦!今天跟随TOM邮箱小编导,来挖掘下邮箱的潜藏技能吧~ 作为经常外出 ...

  7. 理解C#回调函数

    序言 本篇主要学习了C#回调函数的定义使用.欢迎各位大牛的指导. 正文 回调函数是什么? 回调函数就是一个通过函数指针调用的函数.如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调 ...

  8. python 小脚本/自动重复访问网站(快速提高网页访问量)

    来到csdn也快两个月了,前前后后写了20篇博客,但才1800+的访问量,其中恐怕还有300多是我自己点的 有点桑心(┬_┬) 于是打算另辟蹊径,自己刷访问量代码如下,需要自取 import urll ...

  9. oracle数据处理之exp/imp

    oracle 导出/导入数据方法一 exp/imp工具:1 将数据库oracle01完全导出,DBA:sys,密码:123456:用户名Scott 密码123456 导出到D:\emp.dmp中 ex ...

  10. [剑指Offer]66-构建乘积数组

    题目 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]A[1]...A[i-1]A[i+1]...A[n-1].不能使用除法. 题 ...