python函数

3

函数语法

def function_name(parameterlist):

['''comments''']

[functionbody]

 

function_name:函数名称

parameterlist:可选参数,用于指定向函数中传递的参数

comments:可选,表示为函数指定注释,如果指定了该参数,在调用函数时,输入函数名称和左侧小括号,会显示这段信息

functionbody:函数体

函数声明

 

def创建了一个对象并将其赋值给某个变量名

当python运行到def语句时,将生成一个新的函数对象并将其赋值给这个函数名

函数名,是对函数对象的引用

函数名(),是对函数对象的调用,即执行

函数参数

 

  • 形参:形式参数,在定义函数时,函数名后面的括号中的参数是形参
  • 实参:实际参数,在调用函数时,函数名后面的括号中的参数是实参

参数传递

本质上是形参和实参对同一个对象的共享引用,表现为:

  • 不可变对象因为不可改变,可以看做传入了"值"
  • 可变对象因为可以改变,可以看做传入了"指针"

不可变对象:数字、字符串、元组

可变对象:列表、字典

其实都是传入了指针,重新赋值导致形参变量指向了新的对象,即新的引用,和实参变量不再共享引用;原位置改变并没有导致形参变量产生新的引用,仍然是共享引用。

形参在函数体中是局部变量,不可以被声明为全局变量

对形参的重新赋值,不会影响实参

对形参的原位置修改会影响实参

参数匹配顺序

 

1、位置顺序

2、关键字参数

3、默认参数

4、可变长参数

参数匹配与函数调用

定义:常规参数

调用:通过位置次序或关键字名称匹配

>>> def fun1(a,b,c):print(a,b,c)

基于位置调用

>>> fun1(1,2,3)

1 2 3

基于关键字调用,参数顺序不再重要,因为不基于位置

>>> fun1(b=2,c=3,a=1)

1 2 3

混合调用,先匹配基于位置的参数,再匹配基于关键字的参数,

>>> fun1(1,c=3,b=2)

1 2 3

解包调用1,列表

>>> L = [1,2,3]

>>> fun1(L) 直接传入L,会被认为只传入了一个参数

Traceback (most recent call last):

File "<pyshell#44>", line 1, in <module>

fun1(L)

TypeError: fun1() missing 2 required positional arguments: 'b' and 'c'

>>> fun1(*L) 解包L

1 2 3

 

解包调用2,字典

>>> L = [1,2,3]

>>> D = {'a':1,'b':2,'c':3}

>>> fun1(D)

Traceback (most recent call last):

File "<pyshell#47>", line 1, in <module>

fun1(D)

TypeError: fun1() missing 2 required positional arguments: 'b' and 'c'

>>> fun1(**D)

1 2 3

 

定义:默认值参数

调用:无论基于位置还是基于关键字调用,如果在调用时,没有传入参数,使用默认值

>>> def fun1(a,b=2,c):print(a,b,c)

SyntaxError: non-default argument follows default argument

>>> def fun1(a,b,c=4):print(a,b,c)

 

>>> fun1(1,2) 不传入c,则使用默认参数

1 2 4

>>> fun1(1,2,3)

1 2 3

定义:可变长参数

调用:可以传入任意个数的参数,

  • *arge

    函数将这些参数收集到一个元组中,可以被索引或for循环遍历

>>> def fun1(*args):print(type(args),args)

 

>>> fun1(1)

<class 'tuple'> (1,)

>>> fun1(1,2)

<class 'tuple'> (1, 2)

>>> fun1(1,2,3)

<class 'tuple'> (1, 2, 3)

  • **arges

    只对关键字参数有效,函数将这些参数收集到一个字典中

>>> def fun1(**args):print(type(args),args)

>>> fun1(a=1,b=2)

<class 'dict'> {'a': 1, 'b': 2}

>>> fun1(a=1)

<class 'dict'> {'a': 1}

 

 

函数体

流程控制语句

if语句

 

if con1:…

elif con2:…

else:…    

for语句

 

for i in iterator:…

while语句

 

while con1:…

try语句

 

try:可能发生错误的代码

except [ExceptionName [as alias]]:发现对应异常时要执行的语句

else:没有发现异常时要执行的语句    

finally:无论程序中是否有异常产生,都会执行的语句

break 结束整个循环

continue 结束本次循环

pass 占位符,什么也不做

exit() 退出整个程序

变量

  • 全局变量

在函数体外定义(赋值)的变量,或者在函数内部通过global声明的变量是全局变量

在函数内部,

对全局变量的引用不需要声明,因为对变量名的查找遵循LEGB顺序

对全局变量的重新赋值需要global声明,如果不声明,就成了赋值定义了一个局部变量,按照LEGB的顺序,局部变量会覆盖全局变量或内置变量

  • 局部变量

在函数中被定义(赋值)的变量是局部变量,仅在函数运行的过程中存在,在函数调用时生成,在函数退出时消失

 

作用域

python创建、改变或查找变量名都是在命名空间中进行的。作用域就是命名空间。

函数内变量名解析机制为LEGB,即查找顺序

  • 局部作用域 (L)
  • 外层函数作用域(E)
  • 全局作用域(G)
  • 内置作用域(B)

变量与作用域的对应

  • 局部变量的作用域为局部作用域(包括内层函数)

在函数内定义(赋值)的变量名与在函数外定义的变量名并不冲突,即使是相同的变量名

局部变量a与全局变量a,互不冲突即两个变量为a与fun1.a,局部变量a只在函数体内有效

 

  • 全局变量的作用域为全局作用局

  • 在函数体内重新赋值全局变量,或在函数体内声明全局变量,使用global

在函数体内重新赋值全局变量

在函数体内声明全局变量

  • 在函数体内原位置改变对象(注意,这不是重新赋值)不会把变量划分为局部变量,只有对变量赋值才会划分为局部变量

    不可变对象:数字、字符串、元组

    可变对象:列表、字典

 

函数返回值

 

函数通过return语句将计算得到的值(函数调用的结果)传回给调用者

yield向调用者返回一个结果,并记住离开的位置

没有返回语句的函数在执行结束时,返回None对象

posted @ 2020-07-11 22:01  jeancheng  阅读(176)  评论(0编辑  收藏  举报