来自python的【函数、参数、参数传递】

编程入门 行业动态 更新时间:2024-10-25 05:14:39

来自python的【函数、<a href=https://www.elefans.com/category/jswz/34/1771441.html style=参数、参数传递】"/>

来自python的【函数、参数、参数传递】

函数定义

函数是一个代码库,能够提高代码的重复利用率,python中有很多内置函数,也可以自定义函数。

定义函数方法

  • def关键字开头,后跟函数标识符名称和圆括号()
  • 参数和自变量 放在圆括号中间,圆括号之间可以定义参数
  • 一般函数第一句都用来解释说明函数的意义
  • 函数:作为开始,缩进表示一个代码块
  • return[表达式] 结束函数,选择性的返回数据给调用方,若没有return,返回None
  • 一般,参数值和参数名称是按函数声明中定义的顺序匹配的
  • 可以没有参数
  • 没有参数重载的观念,只会覆盖
  • 调用即执行
def 函数名(参数列表):函数体
  • 举例:函数调用直接 函数名(参数1,参数2....)
# 函数和模块
def hello():print('hello world')
hello()#调用 #hello world# 带参数
def area (width,height):print(width,height)return width*height
print(area(1,2)) # 1 2 2
#print(area('12','2')) #TypeError: can't multiply sequence by non-int of type 'str'
# 计算也要符合规则哦
#print(area(1)) #TypeError: area() missing 1 required positional argument: 'height'
# 按照规定来给参数#print(area(,2))               ^
#SyntaxError: invalid syntax  不能省略# 参数默认值
def area1(width=1,height=2):print(width,height)return width*height
print(area1(3,4)) # 3,4,12
print(area1())# 1,2 ,2
#print(area1(,2))会以为脑子不轻此哈哈哈
print(area1(2))# 2,2,4 
# 第一个参数不能省略,只能省略最后的参数
  • 关于函数的参数:可以给参数设置默认值,如果设置默认值,可以不给予参数,或者不给予最后一个参数,这样会使用默认值,但是如果是之前的参数被省略,会报错
  • 在函数中进行某些计算的时候,要注意符合python规则哦,比如字符串不能和数字进行乘数等。

函数参数传递

  • 类型属于对象,变量是没有类型的,a=“string”属于string类型,但a是没有类型的, a相当于是一个对象的引用(指针),而对象就是数据。
  • 对于不可变类型来说,传递的是值,对本身没有影响,只是修改被复制的对象(也就是参数是被复制的对象),所以在函数内部修改不可变类型,对不可变数据没影响
  • 对于可变类型来说,传递的是引用,所以改变后,原始数据也会有影响。【浅拷贝】
# kebia  bukebian
print('------------')
a=1
b=[1,2,3]
def pr(x):x=3print(x)
pr(a) #3
print(a) #1
# 修改的只是拷贝的数据
def pr1(y):y[0]=99print(y)
pr1(b) # [99,2,3]
print(b)#[99,2,3]
  • 函数传递的类型:必需参数,关键字参数,默认参数,不定长参数
    (1)必须参数必须是以顺序传入参数,并且不能省略,除非有默认参数,否则必须参数不能省略,视情况而定,#TypeError: area() missing 1 required positional argument: 'height',上面例子有说。
    (2)关键字参数:使用关键字参数来确定传入的参数值,使用=来明确参数,使用关键字参数允许给予的参数顺序不一致,会自己寻找对应,但是必须每个参数都固定给予,否则会报错。
    (3)默认参数,当没有基于参数的时候,会使用默认参数进行计算,但是不能省略前面的参数,只能省略最后的参数。如果非要省略前面的参数,必须要特定指出后面的参数值。如果只有一些默认参数,默认参数一定要放在最后面
    (4)不定长参数:如果固定了参数的个数,那么给予过的多的参数,会报错,因此就使用不定长参数*表示不知道有多少,不定长参数,会以元组的形式导入。导出。
    如果定义了不定长参数,但是没有基于参数,那么会以空元组的形式出现。
    **则是以字典的形式输入,并且参数一定要是字典形式
# canshu
def a1(str1,str2):print(str1,str2)
#a1(1) TypeError: a1() missing 1 required positional argument: 'str2'
#a1(,3)SyntaxError: invalid syntax
a1(1,2) #1,2def a2(str3,str4,str5):print(str3,str4,str5)
#a2(str4=99,3,6)SyntaxError: positional argument follows keyword argument
# 一个固定 那么所有都得固定
a2(str4=4,str5=5,str3=3)# 3,4,5自己对应
# 可写函数说明
def printinfo( age=35,name): # 默认参数不在最后,会报错 必须要在最后才行"打印任何传入的字符串"print("名字: ", name)print("年龄: ", age)returna3(str6=3,str7=6):print(str6,str7)
a3()#3,6
a3(4)#4,6
a3(str7=9)#3,9 如果省略 要特定哦
#a3(,2)SyntaxError: invalid syntax#a3(4,5,6) 多了def a4(s1,*s2):print(s1) #1print(s2) #(2,3,4,5)print(type(s2)) #class tuple
a4(1,2,3,4,5)
a4(3) # 3 () 空tuple  没有给予不定长参数,那么就会返回空元组# ** 参数 以字典形式导入
def a5(s1,**s2):print(s1)print(s2)
#a5(1,2,3) # 必须指定是字典类型,不然会报错,默认为第一个参数
a5(1,a=2,b=3)#1 {a:2,b:3}
  • 声明函数的时候,参数中*可以单独出现,但是如果单独出现,不一起出现时,*后的数据必须特定指出,也就是使用=关键字传入,相当于是一个分割线,前面的是相对应的,后面是需要关键字传入的,但凡是*后面的 都需要关键字传入
>>> def f(a,b,*,c):
...     return a+b+c
... 
>>> f(1,2,3)   # 报错
Traceback (most recent call last):File "<stdin>", line 1, in <module>
TypeError: f() takes 2 positional arguments but 3 were given
>>> f(1,2,c=3) # 正常
6
>>># *
def test(a,b,*,c,d):print(a,b,c,d)#test(1,2,c=3,6)#SyntaxError: positional argument follows keyword argument

匿名函数

  • 使用lambda 来创建匿名函数,是一个表达式,函数体比def简单,不是代码块,仅仅能在lambda表达式中封装有限的逻辑进去
  • lambda 有自己的命名空间,只能够访问自己内部的变量,参数列表之外的、全局的不能访问
  • 简单来讲,就是定义简单的表达式
  • 也可以使用关键字参数传递参数,也可以设定默认值
  • 可用*传递参数,但是不允许使用/ 在python3.6中不允许,3.8可以
#语法
lambda [arg1[,agr2,agr,,,,]]:expression
sum = lambda agr1,agr2:agr1+agr2
print(sum(1,2))#3#lambda
sum = lambda a1,a2,a3:a1+a2*a3
print(sum(1,2,3)) #7

return[表达式] 语句

  • 用于退出函数,选择性的返回一个表达式或者数据,不带参数的则返回None
  • 可以返回多个参数return a,b,c,输出以元组表示
  • 前面的例子就有 ,不再多说啦~

强制位置参数

  • 必须在调用函数的时候传入参数,使用/表示,/之前的内容都需要强制位置参数/ 之后的参数可以是位置形参,也可以是关键字形参*后的必须是关键字形参
sum2 = lambda a,b=2:a+b
print(sum2(1))#3
print(sum2(a=3,b=4))#7sum3 = lambda a,*,b : a+b
print(sum3(5,b=6))#11
#sum4 = lambda a,/,b=1:a+b #SyntaxError: invalid syntax
#print(sum4(10,2))
# lambda 不允许使用强制位置参数 python3.8 中可以

关于函数参数的问题

  • 可变数据与不可变数据有着不一样的效果。
  • 不可变数据相当于将参数传递过去,重新进行复制,相当于重新开辟一个参数,所以并不影响外围的参数
    -可变数据,也是作为参数传递过去,进行浅拷贝,这个时候是进行引用,如果改变则会改变;如果是全员重新赋值,相当于id改变,所以还是具体情况具体分析
# 函数参数问题
def ys(mylist):"修改的值"print(id(mylist),'before')mylist=[1,2,3,4]print(mylist,'mylist') #1,2,3,,4print(id(mylist),'after')return
mylist = ['a','b','c']
print(id(mylist),'外面')
ys(mylist)
print(mylist) #a,b,c
mylist1 = [1,2,[1,2]]
# 外面id = before id 说明传入的时候是一样 的
# 后面数据改变 id变化 重新赋值了
# 重新赋值了 id改变 互不影响
print('----')
# ys1 改变的是所有的 整体的id被改变 重新赋值 所以互不影响 如果是引用操作 会都改变def ys2 (ml2):print(ml2,id(ml2),'ml2beforeid') #[3, 4, 5, 6, 7, 8, 9] 139891758553800 ml2beforeidprint(ml2[1],id(ml2[1]),'beforeoneid') #4 10914592 beforeoneidml2[1]=99print(ml2,id(ml2),'afterml2id') #[3, 99, 5, 6, 7, 8, 9] 139891758553800 afterml2idprint(ml2[1],id(ml2[1]),'afteroneid') #99 10917632 afteroneidreturnml2=[3,4,5,6,7,8,9]
print(ml2,id(ml2),'外面id') #[3, 4, 5, 6, 7, 8, 9] 139891758553800 外面id
ys2(ml2)
print(ml2,id(ml2),'2次外面id') #[3, 99, 5, 6, 7, 8, 9] 140645756226248 2次外面id

变量的作用域

变量的访问以L(Local) –> E(Enclosing) –> G(Global) –>B(Built-in) 规则查找,即局部查找,局部超找不到,就去寻找全局,再去内置中查找。

# 闭包函数x = int(3.3)x = 0def outer():x = 1def inner():i = 2print(x)inner()outer()  # 1# 全局
x = int(3.3)
x = 0def outer():o = 1def inner():i = 2print(x)inner()outer()  # 0  # 找到全局了 由于0覆盖了3 
# 变量作用域x = int(3.3)x = 0
def outer():x =1def inner():x=2print(x)inner()
outer() #2  局部作用域
  • 函数内可以访问全局变量,但是并不能直接更新或修改值。由于函数内部没有存在该变量,会去全局变量进行寻找,一旦寻找到则开始使用,又由于只是在局部内改变,并不能改变外部原始的值,相当于使用的是一个复制的值,因此修改并不影响外部数据。;
  • 如果在使用外部数据之后又重新定义这个变量,会报错,未经定义就使用,因为变量的查找会先从局部开始
  • global用于声明次变量为全局变量,这样就可以在局部进行修改了,全局变量也会因此改变。
# 访问全局变量a = 10
def a1 (n):print(a) #10n+=aprint(a,n) #10 ,20
a1(10)# a=1
# def a2(n):
#
#     n+=a
#     a=18
#     print(n,a) 未定义就是用a =10
def a3(n):global aa =22print(a)
print(a)#10
a3(1)#22
print(a)#22a = 10
def test():a = a + 1 #修改同名的全局变量,则认为是一个局部变量print(a)
test()
#UnboundLocalError: local variable 'a' referenced before assignmen
  • 函数也可以作为参数哦,回调函数,一般函数的第二行是来写函数的定义的,使用函数名.__doc__可以看见函数的定义
def add(a,b):"这是 add 函数文档"return a+bprint (add.__doc__)
  • 在函数中也可以定义函数参数的以及返回值的类型 ???如何使用 补
    所谓的参数类型只是对参数的一种解释,并不会检查参数的类型。
def function_demo(param_A: int, param_B: float, param_C: list, param_D: tuple) -> dict:pass# pass是暂时代替 表示没有语句的意思# 指定特定类型 ??
def test(a:int,b:list)->dict:print(type(a),type(b))print(a,b)#<class 'str'> <class 'int'>#string 1  没什么差别阿。。return
test('string',1) 

函数参数详解

参数定义

  • 参数分为形参和实参,形参是不占内存地址的,实参占据内存地址,调用函数时传递的参数。
  • 位置参数:也是必须传入的参数,个数、顺序必须对应,否则报错。
  • 默认参数:默认参数必须在最后的位置,否则报错;没有给予实际参数的时候,使用默认参数
  • 关键值参数,对应参数,使用=来寻找对应参数
  • 可变长参数,返回* 元组形式 **字典形式
  • 以及注意使用\ * ** 时候参数的定义,上面有说

参数传递

  • 先放一个链接,说的非常好 参数传递,详情就看这个链接,以及这个链接也很好
  • 关于python参数传递,要分为可变数据、不可变数据来讲。记住,一切皆对象,python为每个对象分配内存空间,但是并非为每个变量分配内存空间。变量更像是一直标签。相同的对象占用同一份资源
  • 相同的对象占用同一份资源,由于python中不可变数据的不可变性,重新更改数据,相当于重新创建了一个新的对象,形参的标签就转为新对象,因此实参没变。
  • 相同的对象占用同一份资源,由于python中可变数据的可变性,形参和实参都指向同一个对象,修改的时候也就都修改了。
  • 这块可以跟随深浅拷贝来看,详情看另一篇~当可变数据和不可变数据都存在的时候,具体情况安装文章进行分析吧
  • 弄清楚赋值 深拷贝 浅拷贝吧,如果在函数定义中重新赋值,给予的是新的对象,也就是新的id地址,如果给予的数据是已经存在的对象(变量相等情况),那么就是会进行修改的哦!
# 函数参数问题
def ys(mylist):"修改的值"print(id(mylist),'before')mylist=[1,2,3,4] # 这里相当于是赋值操作,print(mylist,'mylist') #1,2,3,,4print(id(mylist),'after')return
mylist = ['a','b','c']
print(id(mylist),'外面')
ys(mylist)
print(mylist) #a,b,c
mylist1 = [1,2,[1,2]]
# 外面id = before id 说明传入的时候是一样 的
# 后面数据改变 id变化 重新赋值了
# 重新赋值了 id改变 互不影响# 赋值
a = 10
b = [1,2,3]
print(id(a)) #10914784
print(id(b)) #140644263488264
a =33
b = [3,4,5]
print(id(a)) #10915520
print(id(b)) #139756870023752
# 重新覆盖  赋值就会改变
b1 = b # 这个时候是 传递引用
print(id(b1),id(b)) #139721864788552 139721864788552print('----')
# ys1 改变的是所有的 整体的id被改变 重新赋值 所以互不影响 如果是引用操作 会都改变def ys2 (ml2):print(ml2,id(ml2),'ml2beforeid') #[3, 4, 5, 6, 7, 8, 9] 139891758553800 ml2beforeidprint(ml2[1],id(ml2[1]),'beforeoneid') #4 10914592 beforeoneidml2[1]=99print(ml2,id(ml2),'afterml2id') #[3, 99, 5, 6, 7, 8, 9] 139891758553800 afterml2idprint(ml2[1],id(ml2[1]),'afteroneid') #99 10917632 afteroneidreturnml2=[3,4,5,6,7,8,9]
print(ml2,id(ml2),'外面id') #[3, 4, 5, 6, 7, 8, 9] 139891758553800 外面id
ys2(ml2)
print(ml2,id(ml2),'2次外面id') #[3, 99, 5, 6, 7, 8, 9] 140645756226248 2次外面id

更多推荐

来自python的【函数、参数、参数传递】

本文发布于:2024-02-12 21:01:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1689375.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:参数   函数   python

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!