函数定义与使用
函数基本定义
函数是重用的程序段。
允许给一块语句一个名称,然后可以在程序的任何地方使用这个名称任意多次地运行这个语句块。这被称为 调用函数。
Python函数定义格式
函数通过 def 关键字定义。
def关键字后跟一个函数的标识符名称,然后跟一对圆括号。圆括号之中可以包括一些变量名,该行以冒号结尾。接下来是一块语句,它们是函数体。
def 函数名称([参数,参数,...]): 函数主体代码 [return [返回值]]
范例:定义一个无参有返回值的函数
# coding:UTF-8 def get_info(): """ 定义一个获取信息的功能函数 :return: 返回给调用处的信息内容 """ return "bentley" # 返回处理数据 # 由于get_info()函数上提供有return语句,所以可以直接输出函数返回值 print(get_info()) # 调用并输出get_info()函数的返回结果 return_data = get_info() # 接收函数返回值 print(return_data) # 将函数返回值保存在变量后再输出 print(type(get_info)) # 获取结构类型
bentley bentley <class 'function'>
范例:观察函数类型
# coding:UTF-8 def get_info(): # 定义函数 pass # 函数没有方法体定义时需要写上pass print(type(get_info)) # 获取结构类型 print(type(len)) # 内置序列函数
<class 'function'> <class 'builtin_function_or_method'>
范例:函数互相调用
# coding:UTF-8 def say_hello(): # 定义无参无返回值函数 """ 定义一个信息打印函数,该函数不返回任何数据 """ print("Hello Hello ") # 信息输出 def get_info(): # 定义无参有返回值函数 """ 定义一个获取信息的功能函数 :return: 返回给调用处的信息内容 """ say_hello() # 调用其它函数 return "csdn.bentley.python" # 返回数据 return_data = get_info() # 接收函数返回值 print(return_data) # 将函数返回值保存在变量后再输出
Hello Hello csdn.bentley.python
函数参数传递
范例:定义带参数的函数
# coding:UTF-8 def echo(title, url): # 函数定义 """ 实现数据的回显操作,在接收的数据前追加“ECHO”信息返回 :param title: 要回显的标题信息 :param url: 要回显的网页路径信息 :return: 处理后的Echo信息 """ return "【ECHO】网站名称:{}、主页地址:{}".format(title, url) # 格式化字符串 # 按照函数定义的参数顺序传入所需要的数据 print(echo("csdn", "bentley.python")); # 调用函数并传递所需要的参数内容 # 进行函数调用传递参数时,如果要想改变参数的传入顺序,则也可以使用“参数名称=数值”的形式设置 print(echo(url="bentley.python", title="csdn")); # 调用函数并传递所需要的参数内容
【ECHO】网站名称:csdn、主页地址:bentley.python 【ECHO】网站名称:csdn、主页地址:bentley.python
范例:使用命名关键字参数
# coding:UTF-8 # job与homepage两个参数就必须通过参数名称进行设置 def print_info(name, age, *, job, homepage): print("姓名:%s,年龄:%d,职位:%s,主页:%s" % (name, age, job, homepage)) # 输出信息 print_info("bentley", 18, homepage="csdn.bentley.python", job="你猜") # 函数调用
姓名:bentley,年龄:18,职位:你猜,主页:csdn.bentley.python
范例:定义默认参数
# coding:UTF-8 def echo(title, url="csdn.bentley.python"): # 定义函数 """ 实现数据的回显操作,在接收的数据前追加“ECHO”信息返回 :param title: 要回显的标题信息 :param url: 要回显的网页路径信息,如果不设置则使用“"csdn.bentley.python"”作为默认值 :return: 处理后的Echo信息 """ return "【ECHO】网站名称:{}、主页地址:{}".format(title, url) # 格式化字符串 print(echo("csdn")); # 只传递一个参数 # 传入了全部所需要的参数,这样url参数将不会使用默认值,而使用传递的参数内容 print(echo("baidu","www.baidu.com")) # 调用函数并传递所需要的参数内容
【ECHO】网站名称:csdn、主页地址:csdn.bentley.python 【ECHO】网站名称:baidu、主页地址:www.baidu.com
范例:观察函数对引用数据的影响
# coding:UTF-8 def change_data(list): # 定义函数修改列表数据 list.append("hello") # 添加列表内容 infos = ["bentley"] # 定义一个列表 change_data(infos) # 修改列表数据 print(infos) # 输出修改后的列表
['bentley', 'hello']
可变参数
范例:定义可变参数
可变参数可以使用“*”进行标注,由用户根据实际的需要动态的向函数中传递所需要的参数,而所有接收到的可变参数在函数中都采用元组的形式进行接收
# coding:UTF-8 def math(cmd, *numbers): # 定义函数 """ 定义一个实现数字计算的函数,该函数可以根据传入的数学符号自动对数据计算 :param cmd: 命令符号 :param numbers: 参数名称,该参数为可变参数,相当于一个元祖 :return: 数学计算结果 """ print("可变参数numbers类型:%s,参数数量:%d" % (type(numbers),len(numbers))) sum = 0 # 保存计算总和 if cmd == "+": # 计算符号判断 for num in numbers: # 循环元组 sum += num # 数字累加 elif cmd == "-": # 计算符号判断 for num in numbers: # 循环元组 sum -= num # 数字累减 return sum # 返回计算总和 print("数字累加计算:%d" % math("+", 1, 2, 3, 4, 5, 6)) # 函数调用 print("数字累减计算:%d" % math("-", 3, 5, 6, 7, 9)) # 函数调用
可变参数numbers类型:<class 'tuple'>,参数数量:6 数字累加计算:21 可变参数numbers类型:<class 'tuple'>,参数数量:5 数字累减计算:-30
范例:定义关键字参数
除了使用“*”定义可变参数之外,也可以使用“**”定义关键字参数,在进行参数传递时可以按照“key=value”的形式定义参数项,并可以根据需要传递任意多个参数项。
# coding:UTF-8 def print_info(name, **urls): # 函数定义 """ 定义一个信息输出的操作函数,接收必选参数与关键字参数 :param name: 要输出的姓名信息 :param urls: 一组“key=value”的信息组合 """ print("用户姓名:%s" % name) # 信息输出 print("喜欢的网站:") # 信息输出 for key, value in urls.items(): # 列表迭代输出 print("\t|- %s:%s" % (key, value)) # 信息输出 print_info("李兴华", yootk="www.yootk.com", jixianit="www.jixianit.com") # 函数调用
范例:混合参数
# coding:UTF-8 def print_info(name, age, *inst, **urls): # 定义复合参数 print("用户姓名:%s,年龄:%d" % (name, age)) # 输出必选参数 print("用户兴趣:", end="") # 信息输出 for item in inst: # 输出可变参数 print(item, end="、") # 输出列表项 print("\n喜欢的浏览的网站:") # 信息输出 for key, value in urls.items(): # 输出关键字参数 print("\t|- %s:%s" % (key, value)) # 输出字典项 print_info("李兴华", 18, "唱歌", "看书", yootk="www.yootk.com", jixianit="www.jixianit.com") # 函数调用
函数递归调用
函数递归调用是一种特殊的调用形式,指的是函数自己调用自己的形式,操作形式如图5-5所示,但是在进行函数递归操作的时候必须满足如下的几个条件:
- 递归调用必须有结束条件;
- 每次调用的时候都需要根据需求改变传递的参数内容。
范例:实现数字1 ~ 100之间的累加
# coding:UTF-8 def sum(num): # 函数定义 """ 实现数据累加操作,将给定数值递减后进行累加 :param num: 要进行数据累加的最大值 :return: 数字累加结果 """ if num == 1: # 累加操作结束 return 1 # 返回1 return num + sum(num - 1) # 函数递归调用 print(sum(100)) # 实现1-100的数字累加
范例:计算“1! + 2! + 3! + 4! + 5! + … … + 50!”结果
# coding:UTF-8 def sum(num): # 函数定义 """ 实现数据累加操作,将给定数值递减后进行累加 :param num: 要进行数据累加的最大值 :return: 数字累加结果 """ if num == 1: # 累加操作结束 return 1 # 返回1 return factorial(num) + sum(num - 1) # 函数递归调用 def factorial(num): # 函数定义 """ 实现数据的阶乘计算 :param num: 要进行阶乘的数字 :return: 数字阶乘结果 """ if num == 1: # 阶乘结束条件 return 1 # 递归结束 return num * factorial(num - 1) # 函数递归调用 print(sum(50)) # 函数调用
函数定义深入
变量作用域
范例:观察全局变量与局部变量
使用局部变量
def func(x): print ('x is', x) x = 2 print ('Changed local x to', x) x = 50 func(x) print ('x is still', x)
全局变量与局部变量
# coding:UTF-8 num = 100 # 全局变量 def change_num(): # 函数定义 num = 30 # 局部变量 print("change_num()函数中的num变量:%d" % num) change_num() # 函数调用 print("全局变量num:%d" % num) # coding:UTF-8 num = 100 # 全局变量 def change_num(): # 函数定义 global num # 启用全局变量 num = 30 # 全局变量 print("change_num()函数中的num变量:%d" % num) change_num() # 函数调用 print("全局变量num:%d" % num)
范例:使用有范围标记的变量名称
# coding:UTF-8 GLOBAL_VAR_URL = "www.yootk.com" # 全局变量 def print_info(function_paraemter_title): # 函数参数 local_var_msg = "Hello 小李老师" # 局部变量 范例:使用globals()与locals()函数 # coding:UTF-8 number = 100 # 全局变量 def print_var(): # 函数定义 """ 函数的主要功能是进行一些局部变量的定义同时输出所有变量(包括局部变量以及全局变量) :return: 不返回任何结果(None) """ num = 30 # 局部变量 info = "沐言优拓:www.yootk.com" # 局部变量 print(globals()) # 获取所有全局变量 print(locals()) # 获取所有局部变量 print_var() # 调用函数
范例:获取说明文档信息
# coding:UTF-8 number = 100 # 全局变量 def print_doc(): # 函数定义 """ 函数的主要功能是进行信息打印,同时演示函数注释文档的内容获取 :return: 不返回任何结果(None) """ print("Hello Yootk Hello 小李老师") # 信息输出 print(print_doc.__doc__) # “函数名称.系统变量”
闭包
范例:定义函数闭包结构
# coding:UTF-8 def outer_add(n1): # 定义外部函数 def inner_add(n2): # 定义内部函数 return n1 + n2 # n1为外部函数的参数,与内部函数n2参数相加 return inner_add # 返回内部函数引用 oa = outer_add(10) # 接收外部函数引用 print("加法计算结果:%d" % oa(20)) # 执行内部函数 print("加法计算结果:%d" % oa(50)) # 执行内部函数
范例:内部函数修改外部函数变量内容
# coding:UTF-8 def print_data(count): # 传入一个统计的初期内容 def out(data): # 内部函数 nonlocal count # 修改外部函数变量 count += 1 # 修改外部函数变量 return "第{}次输出数据:{}".format(count,data) # 格式化字符串信息 return out # 返回内部函数引用 oa = print_data(0) # 接收外部函数引用,从0开始计数 print(oa("www.yootk.com")) # 调用内部函数 print(oa("沐言优拓")) # 调用内部函数 print(oa("李兴华老师")) # 调用内部函数
lambda表达式
范例:定义lambda函数
# coding:UTF-8 sum = lambda x, y: x + y; # 定义一个匿名函数,实现两个数字相加(x、y) print(sum(10, 20)) # 调用加法操作
范例:结合闭包使用lambda表达式
# coding:UTF-8 def add(n1): # 函数定义 return lambda n2: n1 + n2 # 实现外部参数n1与内部参数n2的加法计算 oper = add(100) # 获取内部函数引用 print(oper(30)) # 调用加法操作
主函数
范例:定义主函数,并观察“name”
# coding:UTF-8 def main(): # 自定义函数 print("自定义程序主函数,表示程序执行的起点!") # 信息输出 print("更多课程请关注:www.yootk.com") # 信息输出 if __name__ == "__main__": # “__name__”的内容为“__main__” main() # 调用主函数
内置对象函数
callable()函数
范例:使用callable()函数判断函数的可用状态
# coding:UTF-8 print("input()函数是否可以调用:%s" % callable(input)) # 内置input()函数可用,返回True print("“hello”字符串是否可以调用:%s" % callable("hello")) # "hello"是字符串不是函数,返回False def get_info(): # 自定义函数 return "沐言优拓:www.yootk.com" # 返回数据 temp_fun = get_info # 函数引用传递 print("get_info()函数是否可以调用:%s" % callable(get_info)) # 自定义函数可用,返回True print("temp_fun引用对象是否可以调用:%s" % callable(temp_fun)) # 自定义函数可用,返回True
eval()函数
范例:使用eval()动态编译并执行表达式
# coding:UTF-8 num = 10 # 定义全局变量 result = eval("3 * num") # 直接解析字符串定义的程序表达式 print("乘法计算结果:%d" % result) # 输出计算结果
范例:使用全局变量
# coding:UTF-8 global_num = 10 # 全局变量 global_str = "数据加法计算结果:{}" # 全局变量 var_dict = dict(num=global_num, info=global_str) # 字典数据表示全局变量 result = eval("info.format(num * 2)", var_dict) # 调用字符串格式化函数 print(result) # 输出格式化后的字符串数据
范例:将字符串转为其它序列结构
# coding:UTF-8 list_str = "[1,2,3]" # 列表结构字符串 tuple_str = "(1,2,3)" # 元组结构字符串 dict_str = "{1:'one',2:'two',3:'three'}" # 字典结构字符串 list_eval = eval(list_str) # 字符串转为列表 tuple_eval = eval(tuple_str) # 字符串转为元组 dict_eval = eval(dict_str) # 字符串转为字典 print("【list】序列数据:%s,序列类型:%s" % (list_eval, type(list_eval))) # 列表输出 print("【tuple】序列数据:%s,序列类型:%s" % (tuple_eval, type(tuple_eval))) # 元祖输出 print("【dict】序列数据:%s,序列类型:%s" % (dict_eval, type(dict_eval))) # 字典输出
exec()函数
范例:使用exec()函数动态编译并执行程序
# coding:UTF-8 statement = "for item in range(1,10,2):" \ " print(item,end='、')" # 用字符串定义程序语句 exec(statement) # 输出执行结果
compile()函数
范例:使用“eval” 执行模式
# coding:UTF-8 statement = "100 + 200 - 50" # 定义简单表达式 code_eval = compile(statement, "", "eval") # 该操作有返回值,使用eval模式 result = eval(code_eval) # 直接执行编译后的对象 print("计算结果:%d" % result) # 输出执行结果
范例:使用“single”执行模式
# coding:UTF-8 input_data = None # 接收键盘输入数据 statement = "input_data = input('请输入你最喜欢的学校:')" # 定义单行表达式 code_exec = compile(statement, "", "single") # exec与single模式均可 exec(code_exec) # 使用的exec(),没有返回值 print("输入数据为:%s" % input_data) # 输出执行结果
范例:使用“exec”执行模式
# coding:UTF-8 infos = [] # 保存全部键盘输入数据 statement = "for item in range(2):" \ " infos.append(input('请输入你经常访问的网址:'))" # 键盘输入数据并向列表保存 code_eval = compile(statement, "", "exec") # 多行语句,使用exec模式 exec(code_eval) # 执行编译对象 exec("print('经常访问的网址是:%s' % infos)") # 输出执行结果