python笔记--3--函数、生成器、装饰器、函数嵌套定义、函数柯里化

函数

函数定义语法:
  def 函数名([参数列表]):
    ‘‘‘注释‘‘‘
    函数体

函数形参不需要声明其类型,也不需要指定函数返回值类型
即使该函数不需要接收任何参数,也必须保留一对空的圆括号
括号后面的冒号必不可少
函数体相对于def关键字必须保持一定的空格缩进
Python允许嵌套定义函数
在定义函数时,开头部分的注释并不是必需的,但是如果为函数的定义加上这段注释的话,可以为用户提供友好的提示和使用帮助。
Python是一种高级动态编程语言,变量类型是随时可以改变的。Python中的函数和自定义对象的成员也是可以随时发生改变的,可以为函数和自定义对象动态增加新成员。
lambda表达式可以用来声明匿名函数,也就是没有函数名字的临时使用的小函数,尤其适合需要一个函数作为另一个函数参数的场合。

f = lambda x, z, y: x+y+z       # 三个参数
print(f(3, 4, 5))
# 12

g = lambda x, y=2, z=3: x+y+z       # 一个参数,另两个有缺省参数
print(g(1))
# 6
print(g(1, z=4, y=5))
# 10

L = [(lambda x: x**2), (lambda x: x**3), (lambda x: x**4)]      # lambda表达式作为列表元素
print(L[0](2), L[1](2), L[2](2))
# 4 8 16

D = {‘f1‘: (lambda: 2+3), ‘f2‘: (lambda: 2*3), ‘f3‘: (lambda: 2**3)}        # lambda表达式作为字典的值
print(D[‘f1‘](), D[‘f2‘](), D[‘f3‘]())
# 5 6 8

L = [1, 2, 3, 4, 5]
print(list(map(lambda x: x+10, L)))        # 模拟向量运算
# [11, 12, 13, 14, 15]

  内置函数map()可以将一个函数作用到一个序列或迭代器对象上。

print(list(map(str, range(5))))
# [‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘]

def add5(n): return n+5
print(list(map(add5, range(10))))
# [5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

def add(x, y): return x+y
print(list(map(add, range(5), range(5))))
# [0, 2, 4, 6, 8]

  标准库functools中的reduce()函数可以将一个接受2个参数的函数以累积的方式从左到右依次作用到一个序列或迭代器对象的所有元素上。

from functools import reduce

seq = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(reduce(lambda x, y: x+y, seq))
# 45

def add(x, y):
    return x+y

print(reduce(add, range(10)))
# 45
print(reduce(add, map(str, range(10))))
# 0123456789

  内置函数filter将一个函数作用到一个序列上,返回该序列中使得该函数返回值为True的那些元素组成的filter对象。

seq = [‘foo‘, ‘x41‘, ‘?!‘, ‘***‘]

def func(x):
    return x.isalnum()

print(list(filter(func, seq)))
# [‘foo‘, ‘x41‘]

生成器
  包含yield语句的函数可以用来创建生成器对象,这样的函数也称生成器函数。yield语句与return语句的作用相似,都是用来从函数中返回值。与return语句不同的是,return语句一旦执行会立刻结束函数的运行,而每次执行到yield语句并返回一个值之后会暂停或挂起后面代码的执行,下次通过生成器对象的__next__()方法、内置函数next()、for循环遍历生成器对象元素或其他方式显式“索要”数据时恢复执行。生成器具有惰性求值的特点,适合大数据处理。
  Python使用生成器对延迟操作提供了支持。所谓延迟操作,是指在需要的时候才产生结果,而不是立即产生结果。这也是生成器的主要好处。

  python有两种不同的方式提供生成器:
    生成器函数:
      常规函数定义,但是,使用yield语句而不是return语句返回结果。yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行
    生成器表达式:
      类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表。
  注意,生成器只能遍历一次,再次遍历生成器将不会有任何记录。

def fib(n):
    ‘‘‘
    普通函数
    ‘‘‘
    a, b = 0, 1
    while a < n:
        print(a, end=‘ ‘)
        a, b = b, a+b

fib(100)
# 0 1 1 2 3 5 8 13 21 34 55 89

def f():
    ‘‘‘
    生成器函数
    ‘‘‘
    a, b = 0, 1
    while True:
        yield a
        a, b = b, a+b

a = f()
for i in range(20):
    print(a.__next__(), end=‘ ‘)
# 0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181

def gen():
    yield 1
    yield 2
    yield 3

x, y, z = gen()
print(x, y, z)
# 1 2 3

函数嵌套定义
  在Python中,函数是可以嵌套定义的。

def myMap(iterable, op, value):          # 自定义函数
    if op not in ‘+-*/‘:
        return ‘Error operator‘

    def nested(item):                          # 嵌套定义函数
        return eval(str(item)+op+str(value))
    return map(nested, iterable)         # 使用在函数内部定义的函数

print(list(myMap(range(5), ‘+‘, 5)))    # 调用外部函数,不需要关心其内部实现
# [5, 6, 7, 8, 9]
print(list(myMap(range(5), ‘-‘, 5)))
# [-5, -4, -3, -2, -1]
print(list(myMap(range(5), ‘*‘, 5)))
# [0, 5, 10, 15, 20]
print(list(myMap(range(5), ‘/‘, 5)))
# [0.0, 0.2, 0.4, 0.6, 0.8]

  可以使用嵌套函数定义可调用对象。
  任何包含__call__()方法的类的对象都是可调用的。

def linear(a, b):
    def result(x):
        return a * x + b
    return result

class Linear:
    def __init__(self, a, b):
        self.a, self.b = a, b

    def __call__(self, x):
        return self.a * x + self.b

taxes = linear(0.3, 2)      # 函数嵌套方式
print(taxes(5))
# 3.5

taxes = Linear(0.3, 2)      # 类方式
print(taxes(5))
# 3.5

装饰器
  装饰器(decorator)是函数嵌套定义的另一个重要应用。装饰器本质上也是一个函数,只不过这个函数接收其他函数作为参数并对其进行一定的改造之后返回新函数。类中的静态方法、类方法、属性等也都是通过修饰器实现的,Python中还有很多这样的用法。

def check_permission(func):
    def wrapper(*args, **kwargs):
        if kwargs.get(‘username‘) != ‘admin‘:
            raise Exception(‘Sorry. You are not allowed.‘)
        return func(*args, **kwargs)
    return wrapper

class ReadWriteFile(object):
    # 把函数check_permission作为装饰器使用
    @check_permission
    def read(self, username, filename):
        return open(filename, ‘r‘).read()

    def write(self, username, filename, content):
        open(filename, ‘a+‘).write(content)
    # 把函数check_permission作为普通函数使用
    write = check_permission(write)

t = ReadWriteFile()
print(‘Originally.......‘)
print(t.read(username=‘admin‘, filename=r‘e:/test/a123.txt‘))
print(‘Now, try to write to a file........‘)
t.write(username=‘admin‘, filename=r‘e:/test/a123.txt‘, content=‘\nhello world‘)
print(‘After calling to write...........‘)
print(t.read(username=‘admin‘, filename=r‘e:/test/a123.txt‘))

‘‘‘
Originally.......
原始文本
Now, try to write to a file........
After calling to write...........
原始文本
hello world
‘‘‘

函数柯里化
  在计算机科学中,柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术。

  偏函数
    偏函数(partial function)和函数柯里化(function currying)是函数式编程中常用的技术。有时候我们在复用已有函数时可能需要固定其中的部分参数,这除了可以通过默认值参数来实现之外,还可以使用偏函数。
    也可以使用标准库functools提供的partial()方法创建指定函数的偏函数。

from functools import partial

def add3(a, b, c):
    return a+b+c

def add2(a, c):
    return add3(a, 666, c)

print(add2(1, 2))
# 669

add2 = partial(add3, b=666)     # 使用标准库functools提供的partial()方法创建指定函数的偏函数。
print(add2(a=1, c=2))
# 669

  单参函数实现多参函数
    函数柯里化除了可以实现偏函数类似的功能之外,还可以利用单参数函数来实现多参数函数,这要归功于Python对函数嵌套定义和lambda表达式的支持。

def func(a):
    # lambda表达式实现
    return lambda b: a+b

print(func(3)(5))
# 8

def func(a):
    # 函数嵌套定义实现
    def funcNested(b):
        return a+b
    return funcNested

print(func(3)(5))
# 8

def func(a):
    # 多级函数嵌套实现多参数要求
    def funcNested(b):
        def funcNestedNested(c):
            return a+b+c
        return funcNestedNested
    return funcNested

print(func(3)(5)(8))
# 16

原文地址:https://www.cnblogs.com/chuangming/p/8995676.html

时间: 2024-10-01 07:47:38

python笔记--3--函数、生成器、装饰器、函数嵌套定义、函数柯里化的相关文章

五、python函数、装饰器、内置函数、json及模块

一.递归调用 1.一个函数自己调用自己就是递归调用,最多一个函数递归调用自己999次,超过就会出错2.递归必须有一个明确的结束条件3.每次进入更深一层递归时,问题规模相比上次递归都应有所减少4.递归效率不高,少用递归 eg:def test1(): num = int(input('please enter a number:')) if num%2==0:#判断输入的数字是不是偶数 return True #如果是偶数的话,程序就退出了,返回true print('不是偶数请重新输入!') r

函数篇 ---&gt; 装饰器与内置函数

装饰器: 从名字上来看,装饰器就是用来装饰内容的一个工具.本质上是一个闭包 在开发中,装饰器必须要遵守开放封闭原则:对扩展开放,对修改源代码封闭. 在装饰器中,有一个很重要的工具就是@,称之为语法糖,语法糖的本质就是:被装饰的函数名 = 装饰器的名字(被装饰的函数名) 在装饰器的应用上,有一个很简单的例子 计算简易的函数运行时间 import time # 导入time模块 print(time.time()) # 获取时间戳 start_time = time.time() # 开始时间 de

python学习笔记(5)--迭代器,生成器,装饰器,常用模块,序列化

生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: 1 >>> g = (x * x for xin range(10)) 2 >>> g3 <generator object <genexpr> at 0x1022ef630> 此处g就是一个生成器. 迭代器 我们已经知道,可以直接作用于for循环的数据类型有以下几种: 一类是集合数据类型,如list.tuple.dict.set.str等: 一类是gene

python 培训第三章 ,函数,装饰器,模块,内置函数之一函数

目录: 函数示例装饰器模块内置函数一.函数示例: 1.定义函数: def fun(args): '描述信息' 函数体 return 返回值 定义函数的三种形式: 无参函数def foo():print('in the foo') foo() 有参函数: def bar(x,y): print('in the bar') bar(1,2) 空函数: def func(): pass 空函数的应用示例: def put():pass def get():pass def cd():pass def

第二模块&#183;函数编程-第1章 函数、装饰器、迭代器、内置方法

01-鸡汤之人丑就要多读书 02-三元运算 03-文件处理 04-文件处理-二进制模式 05-文件处理-智能检测编码的工具 06-文件处理-写模式操作文件 07-文件处理-追加模式操作文件 08-文件处理-混合操作文件 09-文件操作其他功能 10-文件处理-文件修改功能 11-函数-基本介绍 12-函数-默认参数 13-函数-关键参数 14-函数-非固定参数 15-函数-非固定参数2 16-函数-返回值 17-函数-局部变量 18-函数-在函数里修改全局变量 19-函数-在函数里修改列表数据

函数(三) 装饰器函数

装饰器定义    装饰器其实也就是一个函数,一个用来包装函数的函数,返回一个修改之后的函数值,将新的值赋值原来的函数 2. 装饰器语法 1.函数名可以当作函数的参数 1 import time 2 def timmer(func): 3 #函数名可以当做函数的参数 4 def inner(): 5 start = time.time() 6 func() 7 end = time.time() 8 print(end - start) 9 return inner 10 11 def hahah

装饰器,闭包,高阶函数,嵌套函数

高阶函数代码形式:(1.函数接收的参数是一个函数名 2.函数的返回值是一个函数名) def too(): print('from too') #高阶函数 def foo(): print('from foo') return too a = foo() a() def too(): print('from too') def foo(func): print('from foo') func() a = foo(too) 函数嵌套 定义一个函数,在该函数的代码块中在定义函数(可以一直定义下去)

【前端学习笔记】函数柯里化(自网易云课堂)

1. 函数柯里化通常是指把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的并且返回一个接受余下的参数而且返回结果的新函数的技术. // 1. 最简单的柯里化 // sum函数接受三个参数,并返回求和结果 var sum = function(a,b,c) { return a+b+c; } // 最简单柯里化的sum函数 var sum_curry = function(a){ return function(b,c){ return a+b+c; } } 2. 更泛化的定义是

函数柯里化

柯里化通常也称部分求值,其含义是给函数分步传递参数,每次传递参数后部分应用参数,并返回一个更具体的函数接受剩下的参数,这中间可嵌套多层这样的接受部分参数函数,直至返回最后结果. 因此柯里化的过程是逐步传参,逐步缩小函数的适用范围,逐步求解的过程. 函数可以作为参数传递 函数能够作为函数的返回值 闭包 柯里化的作用 延迟计算.上面的例子已经比较好低说明了. 参数复用.当在多次调用同一个函数,并且传递的参数绝大多数是相同的,那么该函数可能是一个很好的柯里化候选. 动态创建函数.这可以是在部分计算出结

【Scala】高阶函数和柯里化

高阶函数 在数学和计算机科学中,高阶函数是至少满足下列一个条件的函数: - 接受一个或多个函数作为输入 - 输出一个函数 在数学中它们也叫做算子(运算符)或泛函.微积分中的导数就是常见的例子,因为它映射一个函数到另一个函数. 高阶函数的例子 假设有一个函数对给定两个数区间中的所有整数求和: def sumInts(a: Int, b: Int): Int = if(a > b) 0 else a + sumInts(a + 1, b) 如果现在要求连续整数的平方和: def square(x: