Python基础—初识函数(二)

1、给函数参数增加元信息

写好一个函数,然后想为这个函数的参数增加一些额外的信息,这样的话其他使用者就能清楚的知道这个函数应该怎么使用。

使用函数参数注解是一个很好的办法,它能提示程序员应该怎样正确使用这个函数。 例如,下面有一个被注解了的函数:

def add(x:int, y:int) -> int:
    return x + y

python解释器不会对这些注解添加任何的语义。它们不会被类型检查,运行时跟没有加注解之前的效果也没有任何差距。 然而,对于那些阅读源码的人来讲就很有帮助啦。第三方

工具和框架可能会对这些注解添加语义。同时它们也会出现在文档中。

help(add)

Help on function add in module __main__:

add(x: int, y: int) -> int

尽管可以使用任意类型的对象给函数添加注解(例如数字,字符串,对象实例等等),不过通常来讲使用类或者字符串会比较好点。

函数注解只存储在函数的 __annotations__ 属性中。例如:

add.__annotations__
{‘x‘: int, ‘y‘: int, ‘return‘: int}

注解的使用方法可能有很多种,但是它们的主要用途还是文档。 因为python并没有类型声明,通常来讲仅仅通过阅读源码很难知道应该传递什么样的参数给这个函数。 这时候

使用注解就能给程序员更多的提示,从而可以正确的使用函数。

2、有默认参数的函数

定义一个有可选参数的函数是非常简单的,直接在函数定义中给参数指定一个默认值,并放到参数列表最后就行了。

如果默认参数是一个可修改的容器,比如一个列表、集合或者字典,可以使用None作为默认值,就像下面这样:

# 使用一个列表作为默认值
def spam(a, b=None):
    if b is None:
        b = []
    ...

如果并不想提供一个默认值,而是想仅仅测试下某个默认参数是不是有传递进来,可以像下面这样写:

_no_value = object()

def spam(a, b=_no_value):
    if b is _no_value:
        print(‘No b value supplied‘)
    ...

我们测试下这个函数:

spam(1)   >> No b value supplied
spam(1,2)   >> a=1,b=2
spam(1,None)   >> a=1, b=None   # 可以发现到传递一个None值和不传值两种情况是有差别的

注意:默认参数的值仅仅在函数创建的时候赋值一次。

x = 20
def spam(a,b=x):
    print(a,b)

spam(1)  >> 1,20

x = 30
spam(1)   >> 1,20

当我们改变x的值的时候对默认参数值并没有影响,这是因为在函数定义的时候就已经确定了它的默认值了。

其次,默认参数的值应该是不可变的对象,比如None、True、False、数字或字符串。 特别的,千万不要像下面这样写代码:

def spam(a,[]):
    pass

如果这么做了,当默认值在其他地方被修改后将会遇到各种麻烦。这些修改会影响到下次调用这个函数时的默认值。比如:

def spam(a,b=[])
    print(b)
    return b

x = spam(1)

>> []

x.append(10)

x = spam(1)

>>[10]

这种结果不是我们想要的,为了避免这种结果的发生,尽量将默认值设为None,然后在函数里检查它,前面的例子就是这么做的,在测试None值时,is操作符很重要,也是这种操作的关键点,我们时常会写成下面的形式:

def spam(a, b=None):
    if not b:
        b=[]

这么写的问题在于尽管None值确实是被当成False, 但是还有其他的对象(比如长度为0的字符串、列表、元组、字典等)都会被当做False。 因此,上面的代码会误将一些其他输入也当成是没有输入。比如:

spam(1) # OK
x = []
spam(1, x) # 和上面一样,参数可以随意改变
spam(1, 0)   # 数字,不可变类型
spam(1, ‘‘)   # 字符串,不可变类型

3、匿名函数捕获变量值

先看下面代码效果:

x = 10
a = lambda y : x+y

x = 20

b = lambda y : x+y

a(10)  >> 30
b(20)  >> 30

lambda表达式中的x是一个自由变量, 在运行时绑定值,而不是定义时就绑定,这跟函数的默认值参数定义是不同的。 因此,在调用这个lambda表达式的时候,x的值是执行时的值。例如:

x = 10
a(10)   >> 20

x = 20

b(10)  >> 30

如果想让某个匿名函数在定义时就捕获到值,可以将那个参数值定义成默认参数即可,就像下面这样:

x = 10
a = lambda y, x=x: x+y
x = 20
b = lambda y,x=x: x+y

a(10)  >> 20
b(10)  >> 30

通过在一个循环或列表推导中创建一个lambda表达式列表,并期望函数能在定义时就记住每次的迭代值。

# 错误写法

a = [lambda x:x+n for n in range(4)]

for f in a:
    f(0)
    print(f(0))

上面的写法输出全是4,跟刚开始的例子一样,函数运行时,n的值是迭代的最后一个值。

可以通过使用函数默认值参数形式,lambda函数在定义时就能绑定到值。

a = [lambda x,n=n:x+n for n in range(4)]

for f in a:
    f(0)
    print(f(0))

----------------

原文地址:https://www.cnblogs.com/huiyichanmian/p/12103187.html

时间: 2024-11-05 21:47:35

Python基础—初识函数(二)的相关文章

python基础—初识函数

1.python中函数定义:函数是逻辑结构化和过程结构化的一种变成方法. python中函数定义方法: def test(x): ''The function definitions'' x+=1 return x def :定义函数的关键字 test :函数名 ():可定义形参 '''':文档描述,非必要 x+=1: 泛指代码块或程序处理逻辑 return: 定义返回值 2.为什么要使用函数 背景摘要:现在需要写一个监控程序,当CPU,MEMORY,DISK等指标的使用量超过阈值时发送报警邮件

python基础语法(二)

------------------------------------------接 Python 基础语法(一) -------------------------------------------- 2. 元组 tuple和list十分相似,但是tuple是不可变的,即不能修改tuple,元组通过圆括号中用逗号分割的项定义:支持索引和切片操作:可以使用 in 查看一个元素是否在tuple中.空元组():只含有一个元素的元组("a",) #需要加个逗号 优点:tuple比list

python基础篇(二)

python基础篇(二) if:else,缩进和循环控制 A:if的基础格式和缩进 B:循环判断 C:range()函数和len()函数 D:break,contiue和pass语句 for,while循环 函数基础 A:函数的定义和返回值 B:返回值的三种情况 C:函数的注释 函数的进阶(命名空间和作用域) A:内置命名空间 B:全局命名空间 C:局部命名空间 D:全局作用域 E:局部作用域 F:函数的嵌套和作用域链. G:函数名的本质 闭包 ?一:if:else和缩进 A:if的基础格式和缩

python基础——sorted()函数

python基础——sorted()函数 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大小是没有意义的,因此,比较的过程必须通过函数抽象出来. Python内置的sorted()函数就可以对list进行排序: >>> sorted([36, 5, -12, 9, -21]) [-21, -12, 5, 9, 36] 此外,sorted()函数也是一个

第七篇 python基础之函数,递归,内置函数

阅读目录 一 数学定义的函数与python中的函数 二 为何使用函数 背景提要 三 函数和过程 四 函数参数 五 局部变量和全局变量 六 前向引用之'函数即变量' 七 嵌套函数和作用域 八 递归 九 匿名函数 十 函数式编程 十一 内置函数 十二 本节作业 一 数学定义的函数与python中的函数 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因变量,y是x的函数.自变量x的取值范围叫做

Python基础07 函数

Python基础07 函数 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 函数最重要的目的是方便我们重复使用相同的一段程序. 将一些操作隶属于一个函数,以后你想实现相同的操作的时候,只用调用函数名就可以,而不需要重复敲所有的语句. 函数的定义 首先,我们要定义一个函数, 以说明这个函数的功能. def square_sum(a,b): c = a**2 + b**2 return c 这个函数的功能是求两个数的平方和. 首先

python基础——匿名函数及递归函数

python基础--匿名函数及递归函数 1 匿名函数语法 匿名函数lambda x: x * x实际上就是: def f(x): return x * x 关键字lambda表示匿名函数,冒号前面的x表示函数参数. 匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果. 2 匿名函数举例 用匿名函数有个好处,因为函数没有名字,不必担心函数名冲突.此外,匿名函数也是一个函数对象,也可以把匿名函数赋值给一个变量,再利用变量来调用该函数: >>> f = lam

python之内置函数(二)与匿名函数、递归函数初识

一.内置函数(二)1.和数据结构相关(24)列表和元祖(2)list:将一个可迭代对象转化成列表(如果是字典,默认将key作为列表的元素).tuple:将一个可迭代对象转化成元组(如果是字典,默认将key作为元组的元素) 2.相关内置函数(2)reversed:将一个序列翻转,并返回此翻转序列的迭代器. *****slice:构造一个切片模板,用于列表的切片.*** 2-1.reversed()与列表的reverse()区分:列表的reverse()只能列表使用:列表.reverse(),对原列

python基础教程函数参数

python里有很多的内置函数给我们的工作带来了很多发便利,在我们实现某些功能或者优化代码的时候,可以自己定义一个函数,同时我们在定义一个类的时候也会用到函数的一些知识去构造一个方法,这里就涉及到一些关于函数的基础知识和函数传参的知识. 一.函数的相关介绍 1.函数定义:函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可. 函数特性: 减少重复代码 使程序变的可扩展 使程序变得易维护 2.函数的定义示例 定义一个函数要使用def语句,依次写出函数名.括