区分几个概念:
函数式编程:----->函数,最早的编程思想。
面向过程:----->函数
面向对象:----->类class
###过程可以理解为没有返回值的函数。但是在Python中,如果定义的函数没有返回值,会默认返回None,所以在Python中过程和函数基本是一致的。
函数返回值:
没有返回值—》返回None。
有返回值----》返回多个值—》把多个值打包到一个元组中,返回一个元组。
def func1():
"""文档介绍"""
print('in the func1')
return 1,[2,3],(4,5) ###返回一个元组
def func2():
'''文档'''
print("in the func2")
return func1 ##可以返回任何值,返回函数名,则返回该函数的地址。
in the func1
(1, [2, 3], (4, 5))
in the func2
<function func1 at 0x7f31f6eca2f0>
###函数参数调用
遵循两个原则:
- 位置参数调用
- 关键字参数调用
两者最好不要混用,减少错误。
如果两种参数混合调用,根据参数顺序,先判断位置参数调用。
记住一个原则:关键字参数不能写在位置参数前面。
def func3(x,y):
print(x)
print(y)
func3(1,x=2)##第一个参数1是位置参数,付给x,第二个参数还是给x,所以x获得多个值,y无值报错。
Original exception was:
Traceback (most recent call last):
File "/home/justin18chan/PycharmProjects/untitled/function.py", line 23, in <module>
func3(1,x=2)
TypeError: func3() got multiple values for argument 'x'
- 默认参数
定义函数的时候设置默认参数。
调用函数的时候,默认参数非必须传递,如果传递根据传递值设置,没有传递则根据默认值设置。
def func3(x,y=3):##定义的时候设置默认参数y=3
print(x)
print(y)
func3(1,x=2)
- 非固定参数
若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数。可以和关键字参数混合使用。
A.*args args是变量名,可以随意取,关键是变量名前加星号
def func3(x,*args):### *args 会把多传入的参数变成一个元组形式。
print(x)
print(args)
func3(0,[1,2,3])
0
([1, 2, 3],)
B.**kwargs 把N个关键字参数,转换成字典的方式。
def func4(name,**kwargs):
print(kwargs)
print(kwargs['age'])
func4(name='zhangziyi',age='28',sex='Female')
func4(name='zhangzhiyi',**{'age':28,'sex':'Female'})##可以无参数和关键字参数混用。
func4(name='zhangzhiyi',**{'name':'zhangzhiyi','age':28,'sex':'Female'}) ##注意不能有重复的值,字典是唯一的。
{'sex': 'Female', 'age': '28'}
28
{'sex': 'Female', 'age': 28}
28
func4(name='zhangzhiyi',**{'name':'zhangzhiyi','age':28,'sex':'Female'})
TypeError: func4() got multiple values for keyword argument 'name'
- 局部变量与全局变量
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
但是,如果要在函数里面强行改写全局变量,可以通过global在函数里面声明变量为全局变量,然后再修改。
name = '胡歌'
def test():
global name
name = '陈坤'
print(name)
test()
print(name)
陈坤
陈坤
name = '胡歌'
def test():
#global name
name = '陈坤'
print(name)
test()
print(name)
陈坤
胡歌
注意,这里所说的函数内不能修改全局变量,只是针对字符串/数值/元组等简单的变量数据,但是列表/字典/类等复杂的数据结构是可以在函数中的局部变量进行修改的*
list1 = [1,2,3]
tuple1 = ('a','b','c')
age = 18
def reset():
list1[0] = 11
#tuple1[0] = ('aa')
age = 38
print(list1)
print(tuple1[0])
print(age)
reset()
print(list1)
print(tuple1)
print(age)
[11, 2, 3]
a
38
[11, 2, 3]
('a', 'b', 'c')
18
- 递归
1.函数自己调用自己。
2.必须有一个明确的结束条件。
3.每次进入更深一层递归时,问题规模相比上次递归都应有所减少。
4.递归效率不高,应尽可能减少使用递归。
递归层次过多,会导致栈溢出,(在计算机中,函数是通过栈这种数据结构来实现,每当进入一个函数,栈就会多加一层栈帧,每当函数返回,就会减少一层栈帧,由于栈空间有限,递归次数过多会导致栈溢出。)
5.Python针对递归做了保护机制,限制最多递归层数为999层。