目录
函数概述
如果在开发程序时,某块代码需要执行多次,我们并不用每一次使用都去写一遍,我们可以将方法封装到一个模块中,在我们使用时调用这个模块即可,提高了代码的复用性和效率。我们把这个封装代码的模块,就叫做函数。
函数的声明方式
定义方式:
def 函数名(形参列表):
#函数体
def func():
print('函数体')
#------带有参数的函数------------
def func(a):
print(a)
#----调用函数------
func(2)
return关键字
返回结果和结束函数的作用
def func(a,b):
c = a + b
return c #将c返回
# ***调用函数 获取返回值***
d = func(1, 2)
print(d) # 输出3
返回多个值方式
****方式1:列表****
def getnum(a, b):
return [a, b]
print(getnum(1, 2)) # [1, 2]
****方式2:元组(常用)****
def getnum(a, b):
# return (a, b) #可以把括号省去如下:
return a, b #虽然没有括号,但是为元组类型
print(getnum(1, 2)) # (1, 2)
#分别接收参数
c, d = getnum(1, 2)
print(c, d) # 1,2
空函数的定义方式
def func():
pass # pss作为占位符
函数的值传递问题
定义的函数名可以用作变量的方式传递。
def func1():
print("a")
func2 = func1
print(id(func1())) # 140714487871480
print(id(func2)) # 2475804686032
func2() # 输出a
Python的遍历函数
def func1():
print("a")
def func2():
print("b")
def func3():
print("b")
lis = [func1, func2, func3] #使用函数名即可
for f in lis:
f()
# 输出a b c
函数中的参数类型说明
1.标准参数 :有位置函数和默认函数。
2.可变个数的参数 :有可变参数(*args)和关键字参数(**kwargs)。
3.命名关键字参数。
位置参数 (普通参数)
def func(a, b):
print(a + b)
# 使用位置参数,参数位置和个数要保持一致
func(1, 2) # 3
func(1, 2, 3) #报错
默认参数 (有默认值的参数)
def func(a, b=2): #b在参数位置赋了默认值
print(a + b)
func(1) # 输出3 **设置默认参数后,调用时可以不赋值。
错误的语法:有默认值的一定要放到参数最后。例如:
可变参数(*args)
当在写函数时,不知道以后用户调用时传入多少个参数,可以定义可变参数。
def info(name, age, *args):
print(args)
info('Tom', 18, 1, 2, 3) # 输出为(1, 2, 3)
*args中的args为参数名称–可以任意,可变形参封装为元组。
关键字参数 (kwargs–keywordargs)
def info(name, age, **kwargs):
print(kwargs)
info('Tom', 18, gender="m", hobby="sleep")
# 输出{'gender': 'm', 'hobby': 'sleep'}
调用:将可变参数封装为字典。
传递参数时的解包
我们声明了可变参数后,在传递时,可以传递列表或字典的数据类型,传递时就需要通过*args和**kwargs解包的操作后才可当作参数放到参数列表中。例如:
#****列表的解包****
def getnum(name, age, *args):
print(args)
lis = [1, 2, 3]
getnum("Tom", 18, *lis) # 输出([1, 2, 3],)
#****字典的解包****
def info(name, age, **kwargs):
print(kwargs)
dic = {"gender": "m", "hobby": "sleep"}
# info('Tom', 18, dic) #报错:未解包就放入参数列表
#正确操作
info('Tom', 18, **dic) # 输出{'gender': 'm', 'hobby': 'sleep'}
命名关键字参数
*后面的参数,被称为”命名关键字参数” , 例如:
def getnum(a, b, c, *, name, age):
print(a, b, c, name, age)
# getnum(1, 2, 3, "Tom", 18) #报错
#正确形式
getnum(1, 2, 3, name="Tom", age=18)
#*号表示范围。
#*号后面只能是以命名的方式传入参数。
此方式会被解释器认为是:abc为位置参数,name,age为命名参数。命名参数必须如代码方式赋值。
全局变量和局部变量
全局变量
全局变量在整个文件中有效。可以在文件内任何位置使用。
局部变量
只在当前作用域有效,离开所在作用失效,例如函数内声明的变量。
生命周期:当函数执行完毕就销毁。
全局和局部变量名相同时说明
a = 10
def seta():
a = 5
print("局部中的a值:", a)
seta() # 局部中的a值: 5
print("全局中的a值:", a) # 全局中的a值: 10
如果在局部中,设置变量名于全局变量名相同,更改a的值,可以看到全局的a并没有受到影响。也可以看出,在局部中,局部变量的优先级更高。
在局部修改全局变量方式:
在函数中,局部变量名和全局变量名相同时,相当于是又定义了一个局部变量,并不能修改全局变量的值,如果需要修改(引用)全局变量,需要设置global属性。
a = 10
def seta():
global a
a = 5
print("局部中的a值:", a)
seta() # 局部中的a值: 5
print("全局中的a值:", a) # 全局中的a值: 5
可以看到,a设置了global后,在局部中就可以改变全局变量的值了。
在局部中声明全局变量
def func():
global a
a = 1
func()
print(a) # 1
关键字:local和global
返回局部和全局的所有变量。
def seta():
a = 5
b = 2
print(locals())
print(globals())
seta()
#输出如下:
# {'a': 5, 'b': 2}
#{'__name__': '__main__'.......
print(locals()) # {'__name__': '__main__'.......
print(globals()) # {'__name__': '__main__'.......
local()在外部时相当于global()
参数是否可变性说明
看如下代码,执行函数前后值是否改变。
def func(a, b):
print(f"传入的值为{a}和{b}") # 2.传入的值为 10 和['aa', 'bb']
a = 5
b.append("cc")
print(f"局部值经过修改后结果为{a}和{b}") # 3.局部值经过修改后结果为 5 和['aa', 'bb', 'cc']
c = 10
d = ["aa", "bb"]
print(f"全局未调用函数前值为:{c}和{d}") # 1.全局未调用函数前值为:10 和['aa', 'bb']
#调用函数
func(c, d)
print(f"全局调用函数后前值为:{c}和{d}") # 4.全局调用函数后前值为:10 和['aa', 'bb', 'cc']
可以观察到:c不变,d却变了
a不变的原因:a的值是不可变类型,指向内存中的地址值不变,如果改变值,就相当于是赋予了新的地址值。而d为列表,数据类型为可变类型,地址值始终不变。因此可被修改。
结论:(传递参数就是传递了地址值)
1.对于不可变类型,在函数内(局部),每次修改都是让局部变量指向新的地址值(不可变性)。
2.对于可变类型,在函数内,修改时使用的依然是传进来得地址值,进行修改对应空间中的值。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/154564.html