【Python】07-函数详解笔记

函数(Function)是指可重复使用的程序片段。它们允许你为某个代码块赋予名字,允许你 通过这一特殊的名字在你的程序任何地方来运行代码块,并可重复任何次数。这就是所谓的 调用函数。

 

我们已经使用过了许多内置的函数,例如 len 和 range 。

 

函数可以通过关键字 def 来定义。这一关键字后跟一个函数的标识符名称,再跟一对圆括 号,其中可以包括一些变量的名称,再以冒号结尾,结束这一行。

 

随后而来的语句块是函数 的一部分。下面的案例将会展示出这其实非常简单:

def say_hello(): # 该块属于这一函数     print('hello world') # 函数结束say_hello() # 调用函数 say_hello() # 再次调用函数


输出:

hello world hello world

 

它是如何工作的

我们以上文解释过的方式定义名为 say_hello 的函数。这个函数不使用参数,因此在括号中 没有声明变量。函数的参数只是输入到函数之中,以便我可以传递不同的值给它,并获得相 应的结果。

 

要注意到我们可以两次调用相同的函数,这意味着我们不必重新把代码再写一次。

函数参数

函数中的参数通过将其放置在用以定义函数的一对圆括号中指定,并通过逗号予以分隔。当 我们调用函数时,我们以同样的形式提供需要的值。要注意在此使用的术语——在定义函数 时给定的名称称作“形参”(Parameters),在调用函数时你所提供给函数的值称作“实 参”(Arguments)。

def print_max(a, b):     if a > b:             print(a, '是比较大的数')     elif a == b:             print(a, '等于', b)     else:            print(b, '是比较大的数')# 直接传递字面值 print_max(3, 4)x = 5 y = 7 

 

输出

4 是比较大的数7 是比较大的数

 

它是如何工作的

在这里,我们将函数命名为 print_max 并使用两个参数分别称作 a 和 b 。我们使用一个 简单的if...else 语句来找出更大的那个数,并将它打印出来。

 

第一次调用函数 print_max 时,我们以实参的形式直接向函数提供这一数字。

 

在第二次调用 时,我们将变量作为实参来调用函数。print_max(x, y) 将使得实参 x 的值将被赋值给形参 a ,而实参 y 的值将被赋值给形参 b 。在两次调用中, print_max 都以相同的方式工 作。

 

 

局部变量

当你在一个函数的定义中声明变量时,它们不会以任何方式与身处函数之外但具有相同名称 的变量产生关系,也就是说,这些变量名只存在于函数这一局部(Local)。

 

这被称为变量的 作用域(Scope)。

所有变量的作用域是它们被定义的块,从定义它们的名字的定义点开始。

案例:

x = 50 def func(x):     print('x 是:', x)     x = 2     print('改变局部变量x为', x)     func(x) print('x 仍然为', x)

 

输出:

x 为:50改变局部变量x为 2x 仍然为 50

它是如何工作的

 

当我们第一次打印出存在于函数块的第一行的名为 x 的值时,Python 使用的是在函数声明 之上的主代码块中声明的这一参数的值。 

 

接着,我们将值 2 赋值给 x 。x 是我们这一函数的局部变量。因此,当我们改变函数中 x 的值的时候,主代码块中的 x 则不会受到影响。

 

随着最后一句 print 语句,我们展示出主代码块中定义的 x 的值,由此确认它实际上不受 先前调用的函数中的局部变量的影响。

 

 

global 语句 

如果你想给一个在程序顶层的变量赋值(也就是说它不存在于任何作用域中,无论是函数还 是类),那么你必须告诉 Python 这一变量并非局部的,而是全局(Global)的。

我们需要通 过 global 语句来完成这件事。因为在不使用 global 语句的情况下,不可能为一个定义于 函数之外的变量赋值。

你可以使用定义于函数之外的变量的值(假设函数中没有具有相同名字的变量)。然而,这 种方式不会受到鼓励而且应该避免,因为它对于程序的读者来说是含糊不清的,无法弄清楚 变量的定义究竟在哪。

而通过使用 global 语句便可清楚看出这一变量是在最外边的代码块 中定义的。

 

案例:

x = 50def func():global x    print('x 为:', x)    x = 2    print('改变全局变量为', x)func()print('x的值为', x)

输出:

x 为: 50改变全局变量为 2x的值为 2

 

它是如何工作的

global 语句用以声明 x 是一个全局变量——因此,当我们在函数中为 x 进行赋值时,这 一改动将影响到我们在主代码块中使用的 x 的值。

你可以在同一句 global 语句中指定不止一个的全局变量,例如 global x, y, z 。

默认参数值

对于一些函数来说,你可能为希望使一些参数可选并使用默认的值,以避免用户不想为他们 提供值的情况。默认参数值可以有效帮助解决这一情况。

你可以通过在函数定义时附加一个 赋值运算符( = )来为参数指定默认参数值。

 

案例

def say(message, times=1):    print(message * times)say('Hello')say('World', 5)

输出

HelloWorldWorldWorldWorldWorld

 

它是如何工作的

名为 say 的函数用以按照给定的次数打印一串字符串。如果我们没有提供一个数值,则将按 照默认设置,只打印一次字符串。我们通过为参数 times 指定默认参数值 1 来实现这一 点。

 

在第一次使用 say 时,我们只提供字符串因而函数只会将这个字符串打印一次。在第二次使 用 say时,我们既提供了字符串,同时也提供了一个参数 5 ,声明我们希望说(Say)这 个字符串五次。

 

注意 

 

 只有那些位于参数列表末尾的参数才能被赋予默认参数值,意即在函数的参数列表中拥 有默认参数值的参数不能位于没有默认参数值的参数之前。

 

这是因为值是按参数所处的位置依次分配的。举例来说, def func(a, b=5) 是有效的, 但 def func(a=5, b) 是无效的。

关键字参数

如果你有一些具有许多参数的函数,而你又希望只对其中的一些进行指定,那么你可以通过 命名它们来给这些参数赋值——这就是关键字参数(Keyword Arguments)——我们使用命 名(关键字)而非位置(一直以来我们所使用的方式)来指定函数中的参数

这样做有两大优点

其一,我们不再需要考虑参数的顺序,函数的使用将更加容易。

 

其 二,我们可以只对那些我们希望赋予的参数以赋值,只要其它的参数都具有默认参数值。

 

案例

def func(a, b=5, c=10):    print('a 是:', a, ' b 是:', b, ' c是:', c)

func(3, 7)func(25, c=24)func(c=50, a=100)

输出

a 是: 3  b 是: 7  c是:10a 是: 25  b 是: 5  c是:24a 是: 100  b 是: 5  c是:50

它是如何工作的

 

名为 func 的函数有一个没有默认参数值的参数,后跟两个各自带有默认参数值的参数。

 

在第一次调用函数时, func(3, 7) ,参数 a 获得了值 3 ,参数 b 获得了值 7 ,而 c 获得了默认参数值 10 。

 

在第二次调用函数时, func(25, c=24) ,由于其所处的位置,变量 a 首先获得了值 25。然 后,由于命名——即关键字参数——指定,变量 c 获得了值 24 。变量 b 获得默认参数值 5 。

 

在第三次调用函数时, func(c=50, a=100) ,我们全部使用关键字参数来指定值。在这里要注 意到,尽管 a 在 c 之前定义,但我们还是我们在变量 a 之前指定了变量 c 。

 

 

可变参数

有时你可能想定义的函数里面能够有任意数量的变量,也就是参数数量是可变的,这可以通 过使用星号来实现

 

案例

def total(a=5, *numbers, **phonebook):    print('a', a)
    #遍历元组中的所有项目    for num in numbers:        print('num项为:', num)
    #遍历字典中的所有项目    for key, val in phonebook.items():        print(key,val)
print(total(10,1,2,3,Jack=1123,John=2231,Inge=1560))

输出

a 10num项为: 1num项为: 2num项为: 3Jack 1123John 2231Inge 1560None

它是如何工作的

 

当我们声明一个诸如 *param 的星号参数时,从此处开始直到结束的所有位置参数 都将被收集并汇集成一个称为“param”的元组(Tuple)。

 

类似地,当我们声明一个诸如 **param 的双星号参数时,从此处开始直至结束的所有关键字 参数都将被收集并汇集成一个名为 param 的字典(Dictionary)。

 

 

return 语句

 

return 语句用于从函数中返回,也就是中断函数。我们也可以选择在中断函数时从函数中返 回一个值

def maximum(x, y):    if x > y:        return x    elif x == y:        return '两个数相等'    else:        return yprint(maximum(2, 3))

输出:

3

 

它是如何工作的

maximum 函数将会返回参数中的最大值,在本例中是提供给函数的数值。它使用一套简单的if...else 语句来找到较大的那个值并将其返回。

 

要注意到如果 return 语句没有搭配任何一个值则代表着 返回 None 。None 在 Python 中一 个特殊的类型,代表着虚无。举个例子, 它用于指示一个变量没有值,如果有值则它的值便 是 None(虚无) 。

 

每一个函数都在其末尾隐含了一句 return None ,除非你写了你自己的 return 语句。你可 以运行print(some_function()) ,其中 some_function 函数不使用 return 语句,就像这 样:

def some_function():     pass

 

Python 中的 pass 语句用于指示一个没有内容的语句块。

提示: 

有一个名为 max 的内置函数已经实现了“找到最大数”这一功能,所以尽可能地使 用这一内置函数。

 

 

DocStrings 文档字符串

 

Python 有一个甚是优美的功能称作文档字符串(Documentation Strings),在称呼它时通常 会使用另一个短一些的名字docstrings。

 

DocStrings 是一款你应当使用的重要工具,它能够帮 助你更好地记录程序并让其更加易于理解。令人惊叹的是,当程序实际运行时,我们甚至可 以通过一个函数来获取文档!

 

案例

def print_max(x, y):    '''打印两个数值中的最大数。这两个数都应该是整数'''
    # 如果可能,将其转换至整数类型    x = int(x)    y = int(y)    if x > y:        print(x, '大些')    else:        print(y, '大些')print_max(3, 5)print(print_max.__doc__)

输出

5 大些打印两个数值中的最大数。这两个数都应该是整数

 

它是如何工作的

函数的第一行逻辑行中的字符串是该函数的 文档字符串(DocString)。这里要注意文档字符 串也适用于后面相关章节将提到的模块(Modules)与类(Class)

 

该文档字符串所约定的是一串多行字符串,其中第一行以某一大写字母开始,以句号结束。第二行为空行,后跟的第三行开始是任何详细的解释说明。

 

在此强烈建议你在你所有重要功 能的所有文档字符串中都遵循这一约定。

 

我们可以通过使用函数的 __doc__ (注意其中的双下划綫)属性(属于函数的名称)来获取 函数print_max 的文档字符串属性。只消记住 Python 将所有东西都视为一个对象,这其中 自然包括函数。我们将在后面的类(Class)章节讨论有关对象的更多细节。

 

自动化工具可以以这种方式检索你的程序中的文档。因此,我强烈推荐你为你编写的所有重 要的函数配以文档字符串。你的 Python 发行版中附带的 pydoc 命令与 help() 使用文档字 符串的方式类似。

 

 

嵌套函数

python允许创建嵌套函数。也就是说我们可以在函数里面定义函数,而且现有的作用域和变量生存周期依旧不变。

 

需要注意:1.外部函数的变量可以被内部函数所使用,但不能被内部函数修改,若要修改需要添加关键字nonlocal

def max(a,b):    return a if a>b else bprint(max(5,2)) #5def the_max(x,y,z):    c = max(x,y)    return max(c,z)
print(the_max(1,5,3))   #5

输出

55

嵌套函数作用:

1.封装-数据隐藏:外部无法访问“嵌套函数”,

2.减少重复代码

3.闭包

 

 

闭包

啥是闭包?

如果一个函数定义在另一个函数的作用域内,并且引用了外层函数的变量,则该函数称为闭包。

 

闭包是Python所支持的一种特性,它让在非global scope定义的函数可以引用其外围空间中的变量,这些外围空间中被引用的变量叫做这个函数的环境变量。

 

环境变量和这个非全局函数一起构成了闭包。

def outer():    a = 1    def inner():        print(a)    return innerinn = outer()inn()   #1

 

闭包特点:

一个函数返回的函数对象,这个函数对象执行的话依赖非函数内部的变量值,这个时候,函数返回的实际内容如下:
1 函数对象
2 函数对象需要使用的外部变量和变量值


在函数的外部使用内部函数

 

总结

 

我们已经了解了许多方面的函数,但我们依旧还未覆盖到所有类型的函数。不过,我们已经 覆盖到了大部分你每天日常使用都会使用到的 Python 函数。

 

接下来,我们将了解如何创建并使用 Python 模块。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜太小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值