|
目录
前言
一、函数是什么
二、为什么需要函数
三、如何声明/调用一个函数
四、函数的返回值
五、函数的参数
? <1>实参和形参
<2>位置参数
<3>关键字参数
<4>默认参数
<5>可变参数
<6>函数文档?
六、函数变量的作用域
<1>局部变量
<2>全局变量
前言
就最近学习Python的函数的一些笔记
一、函数是什么
函数是组织好的,可重复利用的,用来实现单一或者相关联功能的代码段(块)。在之前Python中的BIF或者print()就是Python中已经封装好的函数(内置函数),而我们自己定义的函数则是用户自定义函数。
二、为什么需要函数
- 复用。对重复使用的代码(功能相同或相关联)将其打包成一个函数,调用时直接调用函数,有时候会大量减少代码的长度,且更加清晰。
- 封装。基于功能进行封装,无需关注内部细节,只需调用即可。
- 清晰。将程序根据功能写成不同的函数或者将重复代码封装成函数,提高整体代码的可读性。
三、如何声明/调用一个函数
? ?在Python创建一个函数用def关键字。例如:
#声明函数使用关键字def
def my_function():? ? ? ? ? #()里为函数参数
? ? ? ? print('hello,Python)
#调用函数时? 函数名+()
my_function()
#打印 hello,Python
?函数的调用和运行机制:当函数my_function()发生调用时,Python会自动往上寻找def? my_function()的定义过程,然后依次执行函数内部代码块部分。
这里注意:函数的声明一定是在函数的调用之前!
四、函数的返回值
有些时候,需要函数返回一些数据来进行报告执行的结果,比如判断一个数的奇偶性。因此,函数需要一个返回值。只需要在函数中使用关键词return,后面跟着需要返回的值即可。
def Parity(number): ? ? """ ? ? 判断一个整数的奇偶性 ? ? 偶数返回True ? ? 奇数返回False ? ? """ ? ? if number%2==0: ? ? ? ? return True ? ? else: ? ? ? ? return False print(Parity(1))
#False
在Python中,并不需要去定义函数的返回值类型,函数可以返回不同类型的值。若无返回值,则默认返回None。另外,若是函数返回多个值,Python默认是元组形式返回。当然用列表返回多个值也可以。
def my_function(): ? ? print("hello") print(my_function()) #hello #None ? ? ?函数无返回值默认None def my_function1(): ? ? return 1,2,3 print(my_function1()) #(1,2,3) ? 函数返回多个值默认以元组形式返回 def my_function2(): ? ? return [1,2,3] print(my_function2()) #[1,2,3] ?以列表形式返回
五、函数的参数
()里自然是函数的参数了。?
? <1>实参和形参
? ? ? ?形参是指函数定义()的参数,实参是指函数调用时实际传递的参数。
def my_function(name): ? ? print("%s还是小白"%name) my_function("57") #打印? 57还是小白
#在这个过程中name就是形参,而57则是实参(实际上传递的参数)? ? ?
<2>位置参数
位置参数时函数调用时实参传递根据对应位置传入值。
def sub(num1,num2): ? ? num=num1-num2 ? ? return num print(sub(1,5)) #-4
#根据对应位置将1,5分别传入num1,num2 print(sub(5,1)) #4
#根据对应位置将5,? 1分别传入num1,num2
<3>关键字参数
关键字传参根据具体名称传入参数值,即在传入实参时明确指出形参的变量名,无需在乎其顺序。
def sub(num1,num2): ? ? num=num1-num2 ? ? return num print(sub(num2=4,num1=5)) #1 #关键字传参不同考虑其位置,根据关键字直接对应5 print(sub(5,num2=2)) #3 #另外注意,若是关键字传参和位置传参一起时位置传参必须放在关键字传参的前面否则报错
<4>默认参数
默认参数是指函数无实参传入时函数默认的取值。
#改变默认参数 def sub(num1,num2=1): ? ? return num1-num2 print(sub(1,2)) ? ? ? ? ? #-1
#保持默认参数 def sub(num1,num2=1): ? ? return num1-num2 print(sub(1)) ? ? ? ? ? #0
?注意:默认参数一定要在非默认参数之后定义,否则就会报错。
<5>可变参数
可变参数也叫收集参数。有时候,我们并不知道函数调用者会传递多少个实参,例如print()函数,因此我们就需要一个参数组来解决,其实就是在形参前加星(*)号。
下面先来看一星(*)参数
#一星(*)可变参数组 def my_function(*args): ? ? return args print(my_function(1,2,3)) ? ? ? ? ?#(1,2,3) list1=[2,3,4] print(my_function(*list1)) ? ? ? ?#(2,3,4) print(my_function(list1)) ? ? ? ? #([2,3,4]) dic={'a':1,'b':2} print(my_function(*dic)) ? ? ? ? ?#('a','b')默认为字典的键 #若想传入其值可调用values() print(my_function(*dic.values())) #(1,2) """ ? ? 注意:*args接受的实参个数不受限制 ?????#*args支持不传值,即可空元组 ?????#若是实参是结构数据类型直接传入,则需在变量前家星(*)号若不带(*)号,则认为?? ? ? ?#传入数据结构类型 ?????#无论传进来什么,*args都会转入元组 """
另外,可变参数和位参结合时,位参一定要放在可变参数的前面,否则,可变参数(*args)会吃掉所有的参数。可变参数若是后面还需指定其他参数,则必须使用关键参数指定。*
def my_function(num,*args): ? ? print(num) ? ? print(args) my_function(1,2,3) #1 #(2,3)
再来看两星(**)参数
#两星(*)可变参数组 def my_function(**kwargs): ? ? return kwargs print(my_function(a=1,b=2,c=3)) ? ? ? ?#{'a':1,'b':2,'c':3} dict1={'a':2,'b':3} print(my_function(**dict1)) ? ? ? ? ? ?#{'a':2,'b':3} dic={1:'a',2:'b'} ? ? ? ? ? ? ? #会报错,因为kwargs不接受传入字典的键为数字 print(my_function(**dic)) ? ? ? ?#必须为strings? """ ? ? ?注意:*kwargs接受的实参个数不受限制 ?????*kwargs传参时键值一起传入 ???????若是实参是字典数据类型直接传入,则需在变量前家星(**)号 ?????**kwargs支持不传值,即可空字典 ?????值打印或者return,**kwargs都会是字典 ?"""
特别注意:在参数混合使用时,kwargs((**)类型)必须放在参数列表的末尾,否则报错。
在函数的定义中,可变参数星(*)号的作用是将传进的多个参数进行”打包“,以一个元组或者字典的形式进行存储。而星(*)号在实参的作用中则是将其”解包“。
list1=[1,2,3,4,5] print(*list1) #1 2 3 4 5?
<6>函数文档?
函数文档就是对于函数的解释说明,与代码注释是一样的。但是它又不同于代码注释。函数文档字符串可以根据__doc__(两边是两天下划线)获取。
def Parity(number): ? ? """ ? ? 判断一个整数的奇偶性 ? ? 偶数返回True ? ? 奇数返回False ? ? """ ? ? if number%2==0: ? ? ? ? return True ? ? else: ? ? ? ? return False print(Parity.__doc__) #判断一个整数的奇偶性 #偶数返回True #奇数返回False
六、函数变量的作用域
<1>局部变量
在函数内部定义的变量是局部变量,而局部变量的作用域就是在函数内,在函数外部是访问不到的。
def my_sum(num1,num2): ? ? num=num1+num2 ? ? return num ? ? ? ? ? ? ? ? ? ?#num,num1,num2皆为函数中定义的,即为局部变量 a=1 b=2 print(my_sum(a,b))? ? ? ? ? ?#3 print(num) ? ? ? ? ? ? ? ? ? ? ? ? #若在函数外部访问局部变量,则会报错。提示name 'num' is not? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#defined,即num并未被定义
<2>全局变量
在函数外部定义,与局部变量相对,作用域是整个模块。例如上述代码中的a,b,在函数的内部是可以访问到的。函数内部可以访问全局变量。
def my_sum(num1,num2): ? ? num=num1+num2 ? ? print(a) ? ? ? ? ? ? ? ? #打印出1 ?函数内部可以访问全局变量a? ? ? return num ? ? ? ? ? ? ? ? ? ? a=1
但是特别注意的是,如果想要直接在函数内部去修改一个全局变量的值,那Python会直接在函数内部定义一个与全局变量同名的局部变量,Python只是给这个局部变量进行赋值,并未对全局变量做任何修改。?这是因为随意修改全局变量的值可能会使程序出现一些bug等,因此Python对其进行“保护”。(这是与c++的不同)
当然,如果用户非要在函数内部去修改全局变量的值,Python也做出了相应的举动。想要在函数内部改变全局变量的值,则需在前面加上关键字global即可。
def my(): ? ? a=2 ? ? print(a,id(a)) ? ? ? ? ? #2 140721348618064 a=1 my() print(a,id(a)) ? ? ? ? ? ? ? #1 140721348618032
def my(): ? ? global a ? ? a=2 ? ? print(a,id(a)) ? ? ? ? ? #2 140721348618064 a=1 print(a,id(a)) ? ? ? ? ? ? ? #1 140721348618032 my() print(a,id(a)) ? ? ? ? ? ? ? #2 140721348618064?
|