前言
前面我们已经接触了很多的库函数,比如ord()函数,split()函数,这些是已经存在的函数。但是,有时候为了方便,我们也会自己进行编写函数。可能很多人不知道为什么要编写函数,这是由于,自定义的函数可以多次使用,并且可以使代码功能更加集中。看完下面的文章你就能够理解了。
函数的定义和使用
函数是软件设计中重要的组成部分,也是进行代码结构优化的重要技术手段,开发者可以利用函数完成某些指定的数据处理逻辑。
函数的基本定义
格式:
def 函数名称([参数,参数…]):
函数主题代码
[return 返回值]
对于函数的返回值,开发者根据自己是否需要,自行决定。
示例:
# coding:UTF-8 def get (): return "I like Python" print(get()) return_data=get() #函数有返回值,故可以用变量或者输出函数来来接收 print(return_data) print(type(return_data))
上面的程序简单的实现了函数的定义。但是函数的使用绝对不只如此的简单,它的用法非常灵活,需要根据程序员实际需要来进行选择。
而在c++中除了void函数,其他的函数都必须要返回函数值,(visual studio 2019编译器)。所以在python中函数也会返回值,返回的数据为None。
学习过其他编程语言的同学应该知道,函数的定义一般都是有参数的,而在c语言和c++中指针参数的传递则成了最难的部分,但是在Python中,所有的变量都是以引用的方式传递的,就简单了很多。
函数参数传递
示例:定义带参数的函数
# coding:UTF-8 def echo(title,url): return "[ECHO]网站名称:{},主页名称:{}".format(title,url) print(echo("力扣刷题","www.likou.com"))
参数的传递方式
(1).不设置参数名称:
例:echo(“力扣刷题网站”,“www.likou.com”)
(2).设置参数名称:
例:echo(url=“www.likou.com”,title=“力扣刷题网站”)
通过上面的程序我们可以看出,设置参数可以交换参数的位置,而不设置参数则必须按照参数的顺序来传递参数。所以二者的差距就是参数的顺序是否可以交换。对于一般的成程序员来说,最好采用不设置参数名称好,如果是不想遵循参数的顺序,就可以使用设置参数名称的方式。
在Python中还提供了一种函数参数名称定义方式,在“*”后的参数必须设置参数名称,在此之前的则不需要设置参数名称。
示例:
def print_info(name,age,*,job,home): print("姓名:%s,年龄:%d,工作:%s,家庭住址:%s" % (name,age,job,home)) print_info("李华",18,home="chinese",job="软件开发工程师")
当然我们也可以定义默认参数,就是定义参数时我们给其赋值,如果后面不赋值,则就使用我们定义的默认值,否则输出我们重新赋予的值。
函数中引用数据修改的问题
我们知道Python中提供的所有数据类型均为引用类型,即如果传递到函数中的参数是一个列表数据,而且在函数体内修改了此列表的类容,则原始列表的数据类容会受到影响。
示例:
def change_data(list): list.append("hello") infos=["Python"] change_data(infos) print(infos) 运行结果: ['Python', 'hello']
图解:
可变参数
为了方便开发者对函数的调用,Python还支持可变参数,即可以由用户根据实际的需要动态的向函数传递参数,而所有接收到的参数在函数中都采用元组的形式进行接收,可变参可以使用“*参数名称”的语法进行标注;
def math(cmd,*numbers): 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): #定义关键字参数 print("用户姓名:%s" % name) print("喜欢的网站:") for key,value in urls.items(): print("\t\- %s:%s" % (key,value)) print_info("李华",wang="www.wang.com",li="www.li.com") 运行结果: 用户姓名:李华 喜欢的网站: \- wang:www.wang.com \- li:www.li.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,"唱歌","看书",sig="www.sign.com",read="www.read.com")
本程序定义了一个包含有混合参数的函数,并且将关键字参数放在了最后,这样才可以保证函数定义的正确性。复合参数的定义顺序为必选参数,默认参数,可变参数,命名关键字参数和关键字参数。
函数递归调用
函数递归调用使一种特殊的函数调用方式,他的好处就是代码量少,方便,但是时间效率太低,一些简单的问题可以使用递归解决,减轻我们的负担。
例如,利用递归函数实现1到100的累加和
def sum(num): if num==1: return num else: return num+sum(num-1) print("%d" % (sum(100)))
实例:
计算1!+2!+3!+·········+50!
def sum(num): if num==1: return num else: return num+sum(num-1) print("%d" % (sum(100))) def sum(num): if num==1: return 1 else: return factorial(num)+sum(num-1) def factorial(num): if num==1: return 1 else: return num*factorial(num-1) print(sum(50)) 运行结果: 31035053229546199656252032972759319953190362094566672920420940313
通过上面的函数我们可以发现,递归函数使用起来十分简单,但是如果要做到完完全全掌握递归的精髓,还需要多次练习,用的多了,才能够熟练的使用递归,否则会造成内存泄露。
函数定义深入
学过C语言或者c++的都知道,在c语言和c++语言中会区分全局变量,局部变量,常量,静态变量。在Python中也有全局变量,局部变量的区分。
变量作用域:在函数中定义的变量只允许本函数使用,称之为局部变量。
而在代码非函数中定义的变量称为全局变量,允许多个函数或代码共同访问。通俗的来讲,变量作用域指的是一个变量可以使用的范围。
Python中为了进行全局变量的标注,提供了global关键字,只需要在变量前利用global进行声明就可以自动将函数中操作的变量设置为全局变量。
提示:关于变量名称解析的LEGB原则
LEGB原则规定了在一个Python程序中变量名称的查找顺序:
(1).L(local):函数类局部变量名称
(2).E(Enclosing Function Locals):外部嵌套函数变量名称
(3).G(Global):函数所在模块或程序文件的变量名称
(4).B(Builtin):内置谋模块的变量名称
实例:观察全局变量和局部变量
#全局变量与局部变量 nums=100 def change_num(): num=30 #局部变量 global nums #全局变量 print("局部变量:%d,全局变量:%d" % (num,nums)) change_num() 显示结果: 局部变量:30,全局变量:100
可能很多人不理解全局变量和局部变量何时使用,当我们需要在多个函数进行使用某一个变量的时候,或者需要经过多种关系进行改变的变量就使用全局变量,对于只需要在某一个函数中使用的变量就使用局部变量。
提示:关于参数名称的另一种定义形式
在代码开发中经常会出现同一变量名被重复使用的情况,为避免使用时出现问题,项目开发定义变量时往往使用一些标记结合变量名称进行定义。例如:
\\ 函数局部变量(本地变量,使用local_var_作为前缀):local_var_name.
\\函数参数(使用function_parameter_作为前缀)function_parameter_name
\\函数全局变量(字母大写,使用GLOBAL_VAR_作为前缀):GLOBAL_VAR_name.
实例:使用globals()与locals()函数
在Python中,提供了两个函数可以动态的获取程序文件中的全局变量(globals())与局部变量(locals()),这两个函数会将所有的变量以字典形式返回。
# coding:UTF-8 number=100 def print_var(): num=30 info="I like Python" print(globals()) print(locals()) print_var()
通过系统给定的函数我们可以得出上下文本的全部变量信息。
在函数中我们也会用“”“”“”来作为注释,哪我们又该如何去获取注释的相关信息?
使用"doc”获取:
实例:
# coding:UTF-8 def change_doc(): """ 在Python中,我们使用的变量一般是局部变量,如果我们要使用全局变量,那么我们就可以用global来进行标注 """ print("Hello Python ") print(change_doc.__doc__) 运行结果: 在Python中,我们使用的变量一般是局部变量,如果我们要使用全局变量,那么我们就可以用global来进行标注