一、函数的基本知识
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可
特性:
- 减少重复代码
- 使程序变的可扩展
- 使程序变得易维护
1.1函数定义规则:
- 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()。
- 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
- 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
- 函数内容以冒号起始,并且缩进。
- return [表达式] 结束函数,选择性地返回一个值给调用方。不带表达式的return相当于返回 None。
1.2语法格式:
def 函数名(参数列表): 函数体
1.3函数的参数:
- 默认参数
- 位置参数
- 关键参数
- 非固定参数 *args 和 **kwargs
默认参数:
调用函数时,如果没有传递参数,则会使用默认参数。

#可写函数说明 def printinfo( name, age = 35 ): "打印任何传入的字符串" print ("名字: ", name); print ("年龄: ", age); return; #调用printinfo函数 printinfo( age=50, name="runoob" ); print ("------------------------") printinfo( name="runoob" );
位置参数:
注意: 位置参数的顺序不可变。
关键字参数:
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

def printme( str ): "打印任何传入的字符串" print (str); return; #调用printme函数 printme( str = "菜鸟教程");
关键字参数的使用不需要指定顺序

#可写函数说明 def printinfo( name, age ): "打印任何传入的字符串" print ("名字: ", name); print ("年龄: ", age); return; #调用printinfo函数 printinfo( age=50, name="runoob" );
非固定参数:
非固定参数或者不定长参数,上述3种参数不同,声明时不会命名,基本语法:
def functionname([formal_args,] *var_args_tuple ): "函数_文档字符串" function_suite return [expression]
加了星号(*)的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数,它就是一个空元组。我们也可以不向函数传递未命名的变量。

# 可写函数说明 def printinfo( arg1, *vartuple ): "打印任何传入的参数" print ("输出: ") print (arg1) for var in vartuple: print (var) return; # 调用printinfo 函数 printinfo( 10 ); printinfo( 70, 60, 50 );
需要注意:
- 关键参数必须放在位置参数之后。
- *args 会把多传入的位置参数变成一个元组(tuple)形式
- *kwargs 会把多传入的关键参数变成一个字典dict形式
1.4全局与局部变量:
在子程序中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量。
全局变量作用域是整个程序,局部变量作用域是定义该变量的子程序。
当全局变量与局部变量同名时:
在定义局部变量的子程序内,局部变量起作用;在其它地方全局变量起作用。
只要有点编程基础,全局和局部变量的概念就应该理解。就不过多赘述了....
需要注意的:
- 对于数字和字符串来说在函数内部默认是不能更改全局变量的
- 如果非要在函数内硬改全局变量,需要在函数内添加 global 函数名,具体见下面global实例1
- 但是这种做法并不推荐
Tuple本身不可更改,所以除了数字类型、字符串类型、元组类型,列表和字典在函数内部调用是可以更改的,具体见实例2

myname = "Rong" def change_name(): global myname #不推荐,不要用 myname = "TanRong" change_name() print(myname)

names_list = ["Jack","Tom","xiaohong"] info_dict = {"name": "Jack", "age":18, "sex":"女"} def change_name(): # global myname # myname = "TanRong" names_list[0] = "xiaoming" info_dict["age"] = 20 change_name() # print(myname) print(names_list) print(info_dict) 输出: ['xiaoming', 'Tom', 'xiaohong'] {'name': 'Jack', 'age': 20, 'sex': '女'}
1.5返回值:
- 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
- 如果未在函数中指定return,那这个函数的返回值为None
二、特殊函数
2.1递归函数:
在函数内部,可以调用其他函数。如果一个函数在内部调用自身本身,这个函数就是递归函数。

def calc(n): print(n) if int(n/2) ==0: return n return calc(int(n/2)) calc(10) 输出: 10 5 2 1
递归特性:
1. 必须有一个明确的结束条件,, 默认深度好像是999
2. 每次进入更深一层递归时,问题规模相比上次递归都应有所减少
3. 递归效率不高,递归层次过多会导致栈溢出(在计算机中,函数调用是通过栈(stack)这种数据结构实现的,每当进入一个函数调用,栈就会加一层栈帧,每当函数返回,栈就会减一层栈帧。由于栈的大小不是无限的,所以,递归调用的次数过多,会导致栈溢出)

data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] def binary_search(dataset,find_num): print(dataset) if len(dataset) >1: mid = int(len(dataset)/2) if dataset[mid] == find_num: #find it print("找到数字",dataset[mid]) elif dataset[mid] > find_num :# 找的数在mid左面 print("