函数

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

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

f = lambda x, z, y: x+y+z       # 三个参数
print(f(3, 4, 5))
# g = lambda x, y=2, z=3: x+y+z # 一个参数,另两个有缺省参数
print(g(1))
#
print(g(1, z=4, y=5))
# 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))
# def add(x, y):
return x+y print(reduce(add, range(10)))
#
print(reduce(add, map(str, range(10))))
#

  内置函数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))
# add2 = partial(add3, b=666) # 使用标准库functools提供的partial()方法创建指定函数的偏函数。
print(add2(a=1, c=2))
#

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

def func(a):
# lambda表达式实现
return lambda b: a+b print(func(3)(5))
# def func(a):
# 函数嵌套定义实现
def funcNested(b):
return a+b
return funcNested print(func(3)(5))
# def func(a):
# 多级函数嵌套实现多参数要求
def funcNested(b):
def funcNestedNested(c):
return a+b+c
return funcNestedNested
return funcNested print(func(3)(5)(8))
#

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

  1. Python学习之--函数/生成器/装饰器

    Function,函数,主要是为了:1提高代码的复用程度,2将程序模块化. 定义函数 在Python中,使用def 用来定义函数,一般函数的定义如下: def name(arg1,arg2,....) ...

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

    生成器 在Python中,一边循环一边计算的机制,称为生成器:generator. 如: >>> g = (x * x for xin range(10)) >>> ...

  3. Python开发——函数【装饰器、高阶函数、函数嵌套、闭包】

    装饰器 装饰器本质就是函数,为其他函数添加附加功能. 原则: 不修改被修饰函数的源代码 不修改被修饰函数的调用方法 装饰器知识储备:装饰器 = 高阶函数 + 函数嵌套 + 闭包 案例:求函数运行时间! ...

  4. python中的迭代器&&生成器&&装饰器

    迭代器iterator 迭代器是访问集合元素的一种方式.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束. 迭代器只能往前不会后退,不过这也没什么,因为人们很少在迭代途中往后退.另外, ...

  5. python中的迭代器 生成器 装饰器

    什么迭代器呢?它是一个带状态的对象,他能在你调用next()方法的时候返回容器中的下一个值,任何实现了__iter__和__next__()(python2中实现next())方法的对象都是迭代器,_ ...

  6. python高级 之(二) --- 类装饰器

    装饰器-初级 在不改变原有函数逻辑功能的基础上,为函数添加新的逻辑功能.使代码可读性更高.结构更加清晰.冗余度更低 简介 """ 闭包: 函数嵌套的格式就是闭包.写装饰器 ...

  7. Python全栈开发:装饰器实例

    #!/usr/bin/env python # -*- coding;utf-8 -*- """ 1.将outer函数放入内存 2.遇见@ + 函数名,则将该函数转换为装 ...

  8. 柯里化函数之Javascript

    柯里化函数之Javascript 定义 依据定义来说,柯里化就是将一个接收"多个"參数的函数拆分成一个或者很多个接收"单一"參数的函数.定义看起来是比較抽象的. ...

  9. 浅析 JavaScript 中的 函数 currying 柯里化

    原文:浅析 JavaScript 中的 函数 currying 柯里化 何为Curry化/柯里化? curry化来源与数学家 Haskell Curry的名字 (编程语言 Haskell也是以他的名字 ...

  10. js函数柯里化,实现bind

    1.柯里化: 把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术. 举个栗子: 一个计算两数之和的函数,需要传递两个参数,柯里化 ...

随机推荐

  1. 【NOIP2013 普及组】车站分级

    [NOIP2013 普及组]车站分级 一.题目 [NOIP2013 普及组]车站分级 时间限制: 1 Sec  内存限制: 128 MB 提交: 3  解决: 0 [提交][状态][讨论版] 题目描述 ...

  2. 深入javascript之原型和原型链

    原型和原型链是js中的难点也是重点,明白了原型和原型链会让我们在后面不管是学习还是工作都会更加高效,并且原型和原型链会是面试中必不可少的话题.看完此篇文章一定会让你对原型,原型链有深刻全面的了解. 一 ...

  3. Redis中redis.conf配置总结

    redis.conf 配置项说明如下:1. Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程  daemonize no2. 当Redis以守护进程方式运行时,Re ...

  4. linux 日常使用命令

    ●安装和登录命令:login.shutdown.halt.reboot.mount.umount.chsh ●文件处理命令:file.mkdir.grep.dd.find.mv.ls.diff.cat ...

  5. RecycleView出现折叠效果--第三方开源--SectionedExpandableGridRecyclerView

    下载地址:https://github.com/ddwhan0123/SectionedExpandableGridRecyclerView/archive/master.zip 具体见源码

  6. GEF入门实例_总结_01_教程、源码、开发环境准备

    一.前言 最近在学Eclipse插件开发,发现了一个比较好的GEF入门教程,并且按照教程上的操作,一步步实现了一个入门Demo,在此感谢作者的贡献. 好记性不如烂笔头,故决定总结一下这段时间的学习心得 ...

  7. Linux-挂载命令

    1.查询与自动挂载 mount:查询系统中已挂载的设备 mount -a :依据配置文件.etc/fsatb的内容,自动挂载 2.挂在命令格式 mount [-t 文件系统] [-o 特殊选项] 设备 ...

  8. 浅学soap--------2

    使用wsdl文件: 生成wsdl <?php require('person.class.php'); // 引入生成wsdl的类文件 require('SoapDiscovery.class. ...

  9. memcached使用libevent 和 多线程模式

    一.libevent的使用 首先我们知道,memcached是使用了iblievet作为网络框架的,而iblievet又是单线程模型的基于linux下epoll事件的异步模型.因此,其基本的思想就是 ...

  10. CodeForces - 150C :Smart Cheater (线段树,求最大连续区间)

    I guess there's not much point in reminding you that Nvodsk winters aren't exactly hot. That increas ...