Python3函数
函数是组织好的,可重复使用的,用来实现单一,或相关功能的代码段。
函数能提高应用的模块性,和代码的重复使用率。
定义一个函数
可以定义一个由自己想要功能的函数,以下是简单规则:
- l 函数代码块是以def关键词开头,后接函数标识符名称和圆括号。
- l 任何传入参数和自变量都必须放在圆括号中,圆括号之间可以用来定义参数。
- l 函数的第一行语句可以选择性的使用文档字符串—用于存放函数说明。
- l 函数内容以冒号起始,并且缩进。
- l return[表达式]结束函数,选择性的返回一个值给调用方。不带表达式的return相当于None
语法:
Python定义函数使用def关键字,一般格式如下:
def 函数名(参数列表) 函数体
默认情况下,参数值和参数名称是按函数声明中的定义顺序匹配的。
参数传递
在python中,类型属于对象,对象是没有类型的。
a = [1,2,3]
a = “Runoob”
以上代码中,[1,2,3]是List类型,“Runoob”是String类型,而变量a是没有类型的,她仅仅是一个对象的引用(一个指针),可以是指向List类型的对象,也可以是指向String类型对象。
可更改和不可更改对象
在Python中,string,tuples和numbers是不可更改的对象,而list,dict等则是可以修改的对象。
不可变类型:变量赋值后a=5后再赋值a=10,这里实际是生成一个int对象10,再让a指向它,而5被抛弃,而不是改变了a的值,相当于重新生成了a。
可变类型:变量赋值la = [1,2,3,4]后再赋值la[2] = 5则是将list la的第三个元素更改,本身la没有动,只是其内部的一部分值被修改了。
python函数的参数传递:
不可变类型:类似于C++的值传递,如整数,字符串,元组。
可变类型:类似于C++引用传递,如列表,字典。
python中一切都是对象,严格意义上我们不能说值传递还是引用传递,我们应该说,传不可变对象和传可变对象。
python传不可变对象实例:
#immutable.py def ChangeInt(a): a = 10 b = 2 ChangeInt(b) print(b)
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python3 immutable.py
2
实例中由int对象2,指向它的变量是b,在传递给ChangeInt函数时,按传值的方式复制了变量b,a和b都指向了同一个int对象,在a=10时,则新生成了一个int对象10,并让a指向了它。
传可变对象实例:
可变对象在函数里修改了参数,那么在调用这个函数的函数里,原始的参数也被改变了。
#mutable.py def changeme(mylist): mylist.append([1,2,3,4]) print("In funciton :",mylist) return mylist = [100,200,300] changeme(mylist) print("outside function : ",mylist)
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python3 mutable.py
In funciton : [100, 200, 300, [1, 2, 3, 4]]
outside function : [100, 200, 300, [1, 2, 3, 4]]
传入函数的和在末尾添加新内容的对象用的是同一个引用
参数
以下是调用函数时可使用的正式参数类型:
- l 必需函数
- l 关键字函数
- l 默认函数
- l 不定长函数
必需参数
必需参数须以正确的顺序传入函数。调用时数量必须和声明时的一样。
关键字参数
关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。
使用关键字允许函数调用时参数顺序与声明时不一致,因为Python解释器能够使用参数名称匹配参数值。
##函数参数使用不需要使用指定顺序: def printinfo(name,age): print("name : ",name) print("age : ",age) return printinfo(age = 20,name = "jack") 运行结果: robot@ubuntu:~/wangqinghe/python/20190828$ python3 seq.py name : jack age : 20
默认参数:
调用函数时,如果没有传递参数,则会使用默认参数
#default.py def printinfo(name,age = 35): print("name :",name) print("age : ",age) return printinfo(age = 20,name = "wangqinghe") print("-----------------") printinfo(name = "wangqinge")
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python3 default.py
name : wangqinghe
age : 20
-----------------
name : wangqinge
age : 35
不定长参数
你可能需要一个函数能处理比当初声明时更多的参数,这些参数叫做不定长参数,和上述两种参数不同,声明时不会命名。
语法如下:
def functionname([formal_args,],*var_args_tuple): function_suite return [expresssion]
加*号的参数会以元组的形式导入,存放所有未命名的变量参数。
#random_length.py def printinfo(arg1,*vartuple): print("output : ") print(arg1) print(vartuple) printinfo(70,60,50)
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python random_length.py
output :
70
(60, 50)
如果在函数调用时没有指定参数,它就是一个空元组,我们也可以不想函数传递未命名的变量:
#unnaming.py def printinfo(arg1,*vartuple): print("output : ") print(arg1) for var in vartuple: print(var) return printinfo(10) printinfo(70,60,50)
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python3 unnaming.py
output :
10
output :
70
60
50
还有一种是参数带有两个**,基本语法如下:
def functionname([formal_args,] **var_args_dict): function_suite return [expression]
加了两个星号,参数会以字典的形式导入
#dic_param.py def printinfo(arg1,**vardict): print("output") print(arg1) print(vardict) printinfo(1,a=2,b=3)
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python3 dic_param.py
output
1
{'a': 2, 'b': 3}
声明函数时,参数中信号*可以单独出现,
def f(a,b,*,c)
return a+b+c
如果单独出现星号后的参数,必须以关键字传入
匿名函数
python使用lambda来创建匿名函数。
所谓匿名,就是不再使用def语句这样标准的形式定义一个函数。
lambda只是一个表达式,函数体比def简单的多
lambda的主体是一个表达式,而不是一个代码块,仅仅能在lambda表达式中封装有限的逻辑进去。
lambda函数拥有自己的命名空间,且不能访问自己参数列表之外或全局命名空间里的参数。
虽然lambda函数看起来只能写一行,却不等同于C/C++的内联函数,后者的目的调用小函数时不占用栈空间从而增加运行效率。
语法:
lambda函数的语法只包含一个语句。
lambda[arg1[,arg2,…argn]]:expression
#lambda.py sum = lambda arg1,arg2:arg1+arg2 print("a + b : ",sum(10,20)) print("a + b : ",sum(20,20))
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python3 lambda.py
a + b : 30
a + b : 40
return语句:
return[表达式]语句用于退出函数,选择性地向调用方返回一个表达式,不带参数值地return语句返回None。
#return.py def sum(arg1,arg2): total = arg1 + arg2 print("Inside fun : ",total) return total total = sum(10,20) print("Outside fun : ",total)
运行结果:
robot@ubuntu:~/wangqinghe/python/20190828$ python3 return.py
Inside fun : 30
Outside fun : 30
变量作用域
Python中,程序变量并不是在哪个位置都可以访问地,访问权限决定于这个变量在哪里赋值地。
变量地作用域决定了在哪一部分可以访问哪个特定地变量名称。python地作用域一共4种,分别是:
- L(local):局部作用域
- E(E你closing):闭包函数外的函数体中
- G(Global)全局作用域
- B(Built-in)内置作用域(内置函数所在模块地范围)
以L->E->G->B地规则去找,即:在局部找不到,就去局部外去找,再找不到就去全局找,再去内置找。
g_count = 0 #全局作用域 def outer(): o_count = 1 #闭包函数外的函数中 def inner(0: i_count = 2 #局部作用域
内置作用域时通过一个叫built地标准模块实现的,但是这个变量名自身并没有放入内置作用域中,所有必须导入这个文件才能使用,在python3中,可以是以下的代码查看到底预定义了哪些变量。
inport builtins
dir(builtins)
Python中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其他代码块(if/elif/else、try/exception、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部亦可以访问
全局变量和局部变量
定义在函数内部的变量拥有一个局部作用域,定义在函数外的拥有全局作用域。
局部变量只能在其被声明的函数内部访问,而全局变量可以在整个程序范围内访问,调用函数时,所有在函数内声明的变量名称都将被加入到作用域中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)