LogoLogo
  • README
  • 前端编程
    • 01 Node JS
    • 02-ES6详解
    • 03-NPM详解
    • 04-Babel详解
    • 05-前端模块化开发
    • 06-WebPack详解
    • 07-Vue详解
    • 08-Git详解
    • 09-微信小程序
  • 人工智能
    • 机器学习
      • 二次分配问题
      • 非负矩阵
      • 概率潜在语义分析
      • 概率图模型
      • 集成学习
      • 降维
      • 距离度量
      • 决策树
      • 逻辑回归
      • 马尔可夫决策过程
      • 马尔可夫链蒙特卡洛法
      • 朴素贝叶斯法
      • 谱聚类
      • 奇异值分解
      • 潜在狄利克雷分配
      • 潜在语义分析
      • 强化学习
      • 社区算法
      • 时间序列模型
      • 特征工程
      • 条件随机场
      • 图论基础
      • 线性分类
      • 线性回归
      • 信息论中的熵
      • 隐马尔科夫模型
      • 支持向量机
      • 主成分分析
      • EM算法
      • Hermite 矩阵的特征值不等式
      • k-means聚类
      • k近邻法
      • PageRank算法
    • 深度学习
      • Pytorch篇
        • 01-线性模型
        • 02-梯度下降法
        • 03-反向传播
        • 04-pytorch入门
        • 05-用pytorch实现线性回归
        • 06-logistic回归
        • 07-处理多维特征的输入
        • 08-加载数据集
        • 09-多分类问题
        • 10-卷积神经网络
        • 11-循环神经网络
    • 图神经网络
      • 图神经网络笔记01
        • 01-图(Graphs)的结构
        • 02-网络的性质和随机图模型
        • 03-网络工具
        • 04-网络中的主题和结构角色
        • 05-网络中的社区结构
      • 图神经网络笔记02
        • 01-深度学习引言
        • 02-神经网络基础
        • 03-卷积神经网络
        • 04-图信号处理与图卷积神经网络
        • 05-GNN的变体与框架-
        • [06-Google PPRGo 两分钟分类千万节点的最快GNN](人工智能/图神经网络/图神经网络笔记02/06-Google%20PPRGo 两分钟分类千万节点的最快GNN.md)
        • 07-序列模型
        • 08-变分自编码器
        • 09-对抗生成网络
  • 日常记录
    • 健身日记
    • 面经记录
    • 自动生成Summary文件
  • 实战项目
    • 谷粒商城
      • 00-项目概述
      • 01-分布式基础-全栈开发篇
      • 02-分布式高级-微服务架构篇
      • 03-高可用集群-架构师提升篇
  • 数据库
    • MySQL笔记
      • 01-MySQL基础篇
      • 02-MySQL架构篇
      • 03-MySQL索引及调优篇
      • 04-MySQL事务篇
      • 05-MySQL日志与备份篇
    • Redis笔记
      • 01-Redis基础篇
      • 02-Redis高级篇
    • 02-Redis篇
  • 算法笔记
    • 01-算法基础篇
    • 02-算法刷题篇
  • 职能扩展
    • 产品运营篇
  • Go编程
    • 01-Go基础
      • 01-Go基础篇
  • Java编程
    • 01-Java基础
      • 01-Java基础篇
      • 02-多线程篇
      • 03-注射与反解篇
      • 04-JUC并发编程篇
      • 05-JUC并发编程与源码分析
      • 06-JVM原理篇
      • 07-Netty原理篇
      • 08-设计模式篇
    • 02 Java Web
      • 01-Mybatis篇
      • 01-Mybatis篇(新版)
      • 02-Spring篇
      • 02-Spring篇(新版)
      • 03-SpringMVC篇
      • 04-MybatisPlus篇
    • 03-Java微服务
      • 01-SpringBoot篇
      • 01-SpringBoot篇(新版)
      • 02-SpringSecurity篇
      • 03-Shiro篇
      • 04-Swagger篇
      • 05-Zookeeper篇
      • 06-Dubbo篇
      • 07-SpringCloud篇
      • 08-SpringAlibaba篇
      • 09-SpringCloud篇(新版)
    • 04-Java中间件
      • 数据库篇
        • 01-分库分表概述
        • 02-MyCat篇
        • 03-MyCat2篇
        • 04-Sharding-jdbc篇
        • 05-ElasticSearch篇
      • 消息中间件篇
        • 01-MQ概述
        • 02-RabbitMQ篇
        • 03-Kafka篇
        • 04-RocketMQ篇
        • 05-Pulsar篇
    • 05-扩展篇
      • Dubbo篇
      • SpringBoot篇
      • SpringCloud篇
    • 06-第三方技术
      • 01-CDN技术篇
      • 02-POI技术篇
      • 03-第三方支付技术篇
      • 04-第三方登录技术篇
      • 05-第三方短信接入篇
      • 06-视频点播技术篇
      • 07-视频直播技术篇
    • 07-云原生
      • 01-Docker篇
      • 02-Kubernetes篇
      • 03-Kubesphere篇
  • Linux运维
    • 01-Linux篇
    • 02-Nginx篇
  • Python编程
    • 01-Python基础
      • 01.配置环境
      • 02.流程控制
      • 03.数值
      • 04.操作符
      • 05.列表
      • 06.元祖
      • 07.集合
      • 08.字典
      • 09.复制
      • 10.字符串
      • 11.函数
      • 12.常见内置函数
      • 13.变量
      • 14.异常和语法错误
      • 15.时间和日期
      • 16.正则表达式
    • 02 Python Web
      • flask篇
        • 01.前言
        • 02.路由
        • 03.模板
        • 04.视图进阶
        • 05.flask-sqlalchemy
        • 06.表单WTForms
        • 07.session与cookie
        • 08.上下文
        • 09.钩子函数
        • 10.flask 信号
        • 11.RESTFUL
        • 13.flask-mail
        • 14.flask+celery
        • 15.部署
        • 16.flask-login
        • 17.flask-cache
        • 18.flask-babel
        • 19.flask-dashed
        • 20.flask-pjax
        • 21.flask上传文件到第三方
        • 22.flask-restless
        • 23.flask-redis
        • 24.flask-flash
        • 25.消息通知
        • 26.分页
    • 03-Python数据分析
      • Matplotlib
      • Numpy
      • Pandas
      • Seaborn
    • 04-Python爬虫
      • 1.准备工作
      • 2.请求模块的使用
      • 3.解析模块的使用
      • 4.数据存储
      • 5.识别验证码
      • 6.爬取APP
      • 7.爬虫框架
      • 8.分布式爬虫
由 GitBook 提供支持
在本页
  • 如何使用函数
  • 定义函数
  • 调用函数
  • 函数引用
  • 函数的参数
  • 形参和实参
  • 关键字参数
  • 默认参数
  • 收集参数
  • 函数文档
  • 返回函数
  • 单个值
  • 多个值
  • 递归
  • 匿名函数lambda
  • 如何使用
  • 语法
  • 实例
  • 列表排序
  • 内嵌函数和闭包
  • 内嵌函数
  • 闭包
  • 装饰器
  • 什么是装饰器?
  • 装饰器有什么用?
  • 简单装饰器
  • @语法糖
  • 如何传参
  • 带参数的装饰器
  • 类装饰器
  • functools.wraps
  • 装饰器顺序
  • 高级函数
  • filter
  • sorted
  • map

这有帮助吗?

在GitHub上编辑
  1. Python编程
  2. 01-Python基础

11.函数

接下来开始学习函数,函数这个知识点很重要,需要认真学习

先来了解下什么是函数?

函数是组织好的,可重复使用的,用来实现单一或相关功能的代码块。

如何使用函数

函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。

函数能提高应用的模块性,和代码的重复利用率,Python提供了许多内建函数,比如print()。

但也可以自己创建函数,这被叫做用户自定义函数。

定义函数

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号()

  • def关键词必须后跟函数名称和带括号的形式参数列表

  • 构成函数体的语句从下一行开始,并且必须缩进

  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明

  • return语句返回一个函数的值。 return没有表达式参数返回None。从函数的末尾掉落也会返回None

现在以Fibonacci数作为例子:

def fib(n):                # 定义一个函数名称,用来计算fibonacci数
    a,b = 1,1              # 赋值
    for i in range(n):    
        print(a,end=' ')
        a,b = b,a+b
    print()

调用函数

已经知道了如何定义函数,那么该如何调用这个函数,接下来继续以上面的那个例子作为示例,进行讲解

def fib(n):                # 定义一个函数名称,用来计算fibonacci数
    a,b = 1,1              # 赋值
    for i in range(n):    
        print(a,end=' ')
        a,b = b,a+b
    print()

fib(10)                    # 调用函数, 并传入一个参数

看,这样就调用了,是不是很简单

运行结果:

1 1 2 3 5 8 13 21 34 55

函数引用

def outFunc():

    print("outFunc()正在被调用")

# 引用函数
outfunc = outFunc
# 通过引用调用函数
outfunc()

# 调用函数
outFunc()



print(id(outfunc))
print(id(outFunc))

运行结果:

outFunc()正在被调用
outFunc()正在被调用
2357814673888
2357814673888

函数的参数

现在已经都知道了如何定义函数和调用函数了,接下来,讲解一下函数里面的参数,这一点很重要,要认真学喔

形参和实参

参数从调用的角度来说,分为形式参数和实际参数。

形参指的是函数创建和定义过程中小括号里的参数,而实参则指的是函数在被调用的过程中传递进来的参数。

下面举个小例子

def person(name):
    print("I am " + str(name))

person("angle")

在person(name)中name是形参,因为这只是代表一个位置,一个变量名而已;而person("angle")中传递的字符串"angle"是实参,因为这是一个具体的内容,是赋值到变量中的值

关键字参数

由于在调用函数的时候,有时候可能会很粗心不小心把参数位置的顺序给弄错了,从而导致函数无法按照预期实现要求。

因此关键字参数是为了解决这个问题而出现的,有了这个就可以很简单的解决这个潜在的问题了。

举个例子

def person(name,age):
    print('{0}的年龄是{1}'.format(name,age))

person("angle","18")

person("18","angle")

person(age="18",name="angle")

person(name="angle",age="18")

运行结果:

angle的年龄是18
18的年龄是angle
angle的年龄是18
angle的年龄是18

从结果可以看到关键字参数是很有用的,因为参数的顺序一不小心弄错,会导致程序无法完成预期的结果的

默认参数

默认参数可以在参数定义的过程中,为形参进行赋值,当函数调用的时候,不传递实参,则默认使用形参的初始值代替。

举个小栗子

def person(name,age,sex='未知'):
    print('{0}的年龄是{1},性别{2}'.format(name,age,sex))


person(name='angle',age='18')
person(name='angle',age='18',sex='男')

是不是很简单,那么继续往下学习

收集参数

什么是收集参数?

在定义函数的时候,不知道这个函数有多少个参数,因为在工作开发的时候,需要根据实际情况添加和删除参数的,这就造成了参数的不确定,由于添加和删除参数工作有点繁琐,所以这时才有了收集参数,收集参数是为了解决这个问题而出现的,收集参数两种,一种是将参数打包元组,一种是以字典形式打包

args

先来讲下第一种,只需要在参数前面加上一个星号(*)就可以了

def person(*args):
    print('{0}的年龄是{1},性别{2}'.format(args[0],args[1]))


person('angle',18)

运行结果

angle的年龄是18,性别未知

参数在传过去的时候,会进行打包成元组传递过去

如果想要单独额外指定参数,可以使用关键字参数

def person(*args,sex='未知'):
    print('{0}的年龄是{1},性别{2}'.format(args[0],args[1],sex))


person('angle','18',sex='男')

运行结果

angle的年龄是18,性别男

星号其实既可以打包又可以解包。什么是解包?

举个小栗子

将列表a传入test参数的收集参数*args中

def test(*args):
    print("{} 个参数".format(len(args)))
    print("第二个参数:{}".format(args[1]))

a = [i for i in range(10)]
print(a)

test(a)

运行结果

Traceback (most recent call last):
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1 个参数
  File "E:/JetBrains/Code_practice_project/test/fibonacci.py", line 8, in <module>
    test(a)
  File "E:/JetBrains/Code_practice_project/test/fibonacci.py", line 3, in test
    print("第二个参数:{}".format(args[1]))
IndexError: tuple index out of range

那么调用test(a)时便会出错,此时需要在a前面加上个星号(*)表示实参需要解包后才能使用

def test(*args):
    print("{} 个参数".format(len(args)))
    print("第二个参数:{}".format(args[1]))

a = [i for i in range(10)]
print(a)

test(*a)

运行结果

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
10 个参数
第二个参数:1

kwargs

另一种收集方式,用两个星号(**)表示

def test(**kwargs):
  for key,value in kwargs.items():
      print("key:{},value:{}".format(key,value))


params = {
    "name":"angle","name":"angle",
    "age":18,
    "sex":"男",
}

test(**params)

运行结果

key:name,value:angle
key:age,value:18
key:sex,value:男

慢慢来解析一下是什么意思?

test(**params)这个是为了收集多个字典参数,打包传递过去
def test(**kwargs)是为了将字典进行解包,和前面讲过的是一样的

函数文档

在程序的时候,有时候为了使代码可读性更高,有时候会在程序旁边进行注释,可是这样影响python代码的美观,这时就可以使用函数文档。

举个例子

def money(dollar):
    """
    美元 --> 人民币
    汇率暂定为6.5
    :param dollar:
    :return: dollar * 6.5
    """
    return dollar * 6.5

m = money(10)

print(m)

运行结果

65.0

这样做还有个好处,这样可以不用打开源码慢慢去找文档注释,这时可以通过特殊属性

__doc__获取(注意doc两边分别两条下划线)
print(money.__doc__)

运行结果

    美元 --> 人民币
    汇率暂定为6.5
    :param dollar:
    :return: dollar * 6.5

在不确定函数的用法的时候,可以使用help()函数来查看函数的文档

print(help(money))

运行结果

Help on function money in module __main__:

money(dollar)
    美元 --> 人民币
    汇率暂定为6.5
    :param dollar:
    :return: dollar * 6.5

None

返回函数

python函数的返回值,可以返回一个值,也能够返回多个值

单个值

def test():
    return 1

print(test())

运行结果

1

多个值

def test():
    return 'angle',18,[1,2,3]

print(test())

运行结果

('angle', 18, [1, 2, 3])

再返回多个值得时候,会打包成元组返回

递归

递归就是不停的调用自己,也就是不停重复做某一个事情

举个小栗子

def f(n):
    if n <= 1:
        return 1
    return f(n-1)*n

n = int(input('请输入一个数字:'))
number = f(n)
print("阶乘结果:{}".format(number))

怎么来理解这个函数了

这里假设输入3

运行结果

请输入一个数字:3
阶乘结果:6

匿名函数lambda

Lambda表达式(有时称为lambda表单)用于创建匿名函数

如何使用

先来看看语法格式,然后看下例子

语法

lambda [parameter_list]:expression

实例

>>> add = lambda x,y:x+y
>>> add(3,5)
8

等价于

>>> def add(x,y):
...     return x+y
...
>>> add(3,5)
8

这样感觉是不是很繁琐,还是感觉lambda好用吧

在举一下其他的例子

比如前面讲过的列表排序

列表排序

>>> a = [(1,2),(4,1),(1,3),(2,-5)]
>>> a.sort(key=lambda v:v[0])
>>> a
[(1, 2), (1, 3), (2, -5), (4, 1)]
>>> a.sort(key=lambda v:v[1])
>>> a
[(2, -5), (4, 1), (1, 2), (1, 3)]

内嵌函数和闭包

讲解了什么是函数,如何使用,现在来学习下什么是内嵌函数和闭包

内嵌函数

内嵌函数其实就是一个函数在其内部在套一个函数,和嵌套循环一样,又可以叫做内部函数

示例:

def outFunc(name):

    print("outFunc()正在被调用")

    def inFunc(name):

        print("inFunc()正在被调用")
        return name

    return inFunc(name)


print(outFunc("angle"))

运行结果:

outFunc()正在被调用
inFunc()正在被调用
angle

是不是很简单,但是这个只能调用outFunc()函数,而inFunc()函数只能在outFunc()函数中调用,而在outFunc()函数外调用,会进行报错,因为inFunc()函数的作用域只在outFunc()函数内才生效

def outFunc(name):

    print("outFunc()正在被调用")

    def inFunc(name):

        print("inFunc()正在被调用")
        return name

    return inFunc(name)

inFunc("angle")

运行结果:

def outFunc(name):

    print("outFunc()正在被调用")

    def inFunc(name):

        print("inFunc()正在被调用")
        return name

    return inFunc(name)

inFunc("angle")

闭包

python中的闭包从表现形式上定义为:如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包。

举个小栗子

def outFunc(param1):

    def inFunc(param2):

        print("inFunc()函数,param2参数值为{}".format(param2))

        return param1 * param2

    # 注意,这里返回的闭包的结果
    return inFunc

test = outFunc(3)
# 这里其实调用的是inFunc(param2),参数5传给的是param2
result = test(5)
print(result)

运行结果:

inFunc()函数,param2参数值为5
15

可以将

test = outFunc(3)
result = test(5)

缩写为

result = outFunc(3)(5)

这两者之间是等价的

def outFunc(param1):

    def inFunc(param2):

        print("inFunc()函数,param2参数值为{}".format(param2))

        return param1 * param2
    return inFunc

result = outFunc(3)(5)
print(result)

运行结果

inFunc()函数,param2参数值为5
15

装饰器

什么是装饰器?

装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。

装饰器有什么用?

抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能,也称之为扩展功能。

先看一个简单的例子:

def foo():
    print("this is a foo")

foo()

现在有一个新的需求,希望可以记录下函数的执行日志,于是在代码中添加日志代码

import logging


def foo():
    print("this is a foo")

    logging.warning("foo is running")


foo()

可是如果函数 bar()、bar2() 也有类似的需求,怎么做?再写一个 logging 在 bar 函数里?这样就造成大量雷同的代码,为了减少重复写代码,我们可以这样做,重新定义一个新的函数:专门处理日志 ,日志处理完之后再执行真正的业务代码

import logging


def use_logging(func):
    logging.warning("foo is running")
    func()

def foo():
    print("this is a foo")

use_logging(foo)

这样做逻辑上是没问题的,功能是实现了,但是调用的时候不再是调用真正的业务逻辑 foo 函数,而是换成了 use_logging 函数,这就破坏了原有的代码结构, 现在不得不每次都要把原来的那个 foo 函数作为参数传递给 use_logging 函数,那么有没有更好的方式的呢?当然有,答案就是装饰器。

简单装饰器

import logging


def use_logging(func):

    def wrapper():
        logging.warning("foo is running")
        # 注意,这把foo()函数当做参数传递进来了,执行func()相当于执行foo()
        return func()

    return wrapper


def foo():
    print("this is a foo")

# 因为装饰器use_logging(foo)返回的是函数对象wrapper,这条语句相当于 foo = wrapper
foo = use_logging(foo)
# foo = wrapper
# 执行foo()就相当于执行wrapper()
foo()
# wrapper()

# 上面的两句等价于下面的语句
# use_logging(foo)()

use_logging 就是一个装饰器,它一个普通的函数,它把执行真正业务逻辑的函数 func 包裹在其中,看起来像 foo 被 use_logging 装饰了一样,use_logging 返回的也是一个函数,这个函数的名字叫 wrapper。在这个例子中,函数进入和退出时 ,被称为一个横切面,这种编程方式被称为面向切面的编程。

@语法糖

@符号是装饰器的语法糖

借鉴维基百科的看下什么是语法糖?

语法糖(Syntactic sugar),也译为糖衣语法,是由英国计算机科学家彼得·蘭丁发明的一个术语,指计算机语言中添加的某种语法,这种语法对语言的功能没有影响,但是更方便程序员使用。 语法糖让程序更加简洁,有更高的可读性

import logging


def use_logging(func):

    def wrapper():
        logging.warning("foo is running")
        return func()

    return wrapper

@use_logging
def foo():
    print("this is a foo")


foo()

有了@,就可以省去foo = use_logging(foo)这一句了,能够直接调用foo()得到想要的答案,并且提高了程序的可重复利用性,并增加了程序的可读性

如何传参

传入一个参数

import logging


def use_logging(func):

    # 传入参数name
    def wrapper(name):
        logging.warning("{} is running".format(name))
        return func(name)

    return wrapper

@use_logging
def foo(name):
    print("this is a {}".format(name))


foo("foo")

传入多个参数

import logging


def use_logging(func):

    def wrapper(*args,**kwargs):
        logging.warning("{} is running".format(func.__name__))
        return func(*args,**kwargs)

    return wrapper

@use_logging
def foo(name,age,**params):
    print("name:{},age:{},sex:{}".format(name,age,params.get("sex")))


params = {
    "sex":"男"
}

foo("angle","18",**params)

带参数的装饰器

装饰器还有更大的灵活性,例如带参数的装饰器,在上面的装饰器调用中,该装饰器接收唯一的参数就是执行业务的函数 foo 。装饰器的语法允许在调用时,提供其它参数,比如@decorator(a)。这样,就为装饰器的编写和使用提供了更大的灵活性。比如,可以在装饰器中指定日志的等级,因为不同业务函数可能需要的日志级别是不一样的。

import logging


def use_logging(level):

    def decorator(func):

        def wrapper(*args,**kwargs):

            if level == "warning":
                logging.warning("{} is running".format(func.__name__))
            elif level == "info":
                logging.info("{} is running".format(func.__name__))

            return func(*args,**kwargs)

        return wrapper

    return decorator

@use_logging(level="info")
def foo(name,age,**params):
    print("name:{},age:{},sex:{}".format(name,age,params.get("sex")))


params = {
    "sex":"男"
}

foo("angle","18",**params)

上面的 use_logging 是允许带参数的装饰器。它实际上是对原有装饰器的一个函数封装,并返回一个装饰器。我们可以将它理解为一个含有参数的闭包。当我 们使用@use_logging(level="warn")调用的时候,Python 能够发现这一层的封装,并把参数传递到装饰器的环境中。

@use_logging(level="warn")`等价于`@decorator

等价于如下

import logging


def use_logging(level):

    def decorator(func):

        def wrapper(*args,**kwargs):

            if level == "warning":
                logging.warning("{} is running".format(func.__name__))
            elif level == "info":
                logging.info("{} is running".format(func.__name__))

            return func(*args,**kwargs)

        return wrapper

    return decorator

def foo(name,age,**params):
    print("name:{},age:{},sex:{}".format(name,age,params.get("sex")))


params = {
    "sex":"男"
}

# 调用最外围函数
test = use_logging(level="warning")
# test = decorator
test(foo)("angle","18",**params)

类装饰器

没错,装饰器不仅可以是函数,还可以是类,相比函数装饰器,类装饰器具有灵活度大、高内聚、封装性等优点。使用类装饰器主要依靠类的__call__方法,当使用 @ 形式将装饰器附加到函数上时,就会调用此方法。

class Foo(object):
    def __init__(self, func):
        self._func = func

    def __call__(self):
        print ('class decorator runing')
        self._func()
        print ('class decorator ending')

@Foo
def bar():
    print ('bar')

bar()

functools.wraps

使用装饰器极大地复用了代码,但是他有一个缺点就是原函数的元信息不见了,比如函数的docstring、name、参数列表,先看例子:

# 装饰器
def logged(func):
    def with_logging(*args, **kwargs):
        print( func.__name__)      # 输出 'with_logging'
        print (func.__doc__)       # 输出 None
        return func(*args, **kwargs)
    return with_logging

# 函数
@logged
def f(x):
   """does some math"""
   return x + x * x

logged(f)

不难发现,函数 f 被with_logging取代了,当然它的docstring,__name__就是变成了with_logging函数的信息了。好在我们有functools.wraps,wraps本身也是一个装饰器,它能把原函数的元信息拷贝到装饰器里面的 func 函数中,这使得装饰器里面的 func 函数也有和原函数 foo 一样的元信息了。

from functools import wraps
def logged(func):
    @wraps(func)
    def with_logging(*args, **kwargs):
        print func.__name__      # 输出 'f'
        print func.__doc__       # 输出 'does some math'
        return func(*args, **kwargs)
    return with_logging

@logged
def f(x):
   """does some math"""
   return x + x * x

装饰器顺序

假如一个函数同时有多个装饰器如下

def a(func):

    def wrapper(*args,**kwargs):
        print("a")
        return func(*args,**kwargs)

    return wrapper


def b(func):
    def wrapper(*args, **kwargs):
        print("b")
        return func(*args, **kwargs)

    return wrapper


def c(func):
    def wrapper(*args, **kwargs):
        print("c")
        return func(*args, **kwargs)

    return wrapper


def d(func):
    def wrapper(*args, **kwargs):
        print("d")
        return func(*args, **kwargs)

    return wrapper

@a
@b
@c
@d
def e1():
    print("e1")

def e2():
    print("e2")

e1()
print("-"*30)
a(b(c(d(e2))))()

运行结果

a
b
c
d
e1
------------------------------
a
b
c
d
e2

执行顺序是从里到外,最先调用最里层的装饰器,最后调用最外层的装饰器

高级函数

接下来讲下高级函数,这些都是python的内置函数

filter

简述

filter()函数用于过滤序列,过滤掉不符合条件的元素,返回一个迭代器,产生可迭代对象,如果转换为列表,需要使用list()。

该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。是真的。 如果function为None,则返回true的项。

语法

filter(function or None,iterable) - > filter对象

参数

  • function:函数

  • iterable:可迭代的对象

返回值

返回一个可迭代对象

实例

>>> def isOdd(n):
...     return n%2 == 1
...
>>> test = filter(isOdd,[1,2,3,4,5,6,7])
>>> new_test = list(test)
>>> new_test
[1, 3, 5, 7]

sorted

简述

sorted()函数从iterable中的项返回一个新的排序列表

语法

sorted(iterable,*,key = None,reverse = False )

参数

  • iterable -- 可迭代对象。

  • key指定一个参数的函数,用于从每个列表元素中提取比较键:key=str.lower。默认值为None (直接比较元素)。

  • reverse是一个布尔值。如果设置为True,则对列表元素进行排序,并且反转

返回值

一个参数返回对象类型, 三个参数,返回新的类型对象

实例

>>> a = [5,6,7,3,6]
>>> a
[5, 6, 7, 3, 6]
>>> sorted(a)
[3, 5, 6, 6, 7]
>>> sorted(a,reverse=True) # 反转
[7, 6, 6, 5, 3]
>>> a.sort() # 注意sort只为list定义,而sorted()函数可以接收任何的iterable
>>> a        
[3, 5, 6, 6, 7]

>>> test = [4,3,8,7,6,1,0,2]
>>> test
[4, 3, 8, 7, 6, 1, 0, 2]

# 利用key进行排序
>>> result = sorted(test,key=lambda x:x)
>>> result
[0, 1, 2, 3, 4, 6, 7, 8]
>>> result = sorted(test,key=lambda x:-x)
>>> result
[8, 7, 6, 4, 3, 2, 1, 0]

温馨提示

sort 与 sorted 区别:

sort 是应用在 list 上的方法,sorted 可以对所有可迭代的对象进行排序操作。

list 的 sort 方法返回的是对已经存在的列表进行操作,而内建函数 sorted 方法返回的是一个新的 list,而不是在原来的基础上进行的操作。

map

简述

map() 会根据提供的函数对指定序列做映射。

第一个参数 function 以参数序列中的每一个元素调用 function 函数,返回包含每次 function 函数返回值的新列表。

语法

map(func, *iterables)

参数

  • function:函数

  • iterable:一个或多个序列

返回值

返回迭代器

实例

>>> def func(x):
...     return x*2
...
>>> map(func,[1,2,3,4,5])
<map object at 0x000001B76E4DABA8>
>>> list(map(func,[1,2,3,4,5]))
[2, 4, 6, 8, 10]
上一页10.字符串下一页12.常见内置函数

最后更新于3年前

这有帮助吗?

img