语法
def fun(parameters): #函数文档字符串 function_suite return [expression]
参数传递
可变与不可变对象
python中,strings,tuples和numbers是不可更改的对象,而list,dict等则是可以更改的对象
不可变类型:
变量赋值a=5再复制a=10,这里实际新生成一个int值对象,再让a指向它,而5被丢弃,不是改变a的值,相当于新生成了a。类似C++,如整型,字符串,元组,传递的只是参数的值,没有影响参数对象本身,仅仅是在函数内部修改另一个复制的复制的对象的值,不会影响参数对象本身
可变类型
变量赋值list1=[1,2,3,4],后再复制list1[1]=3,是将list1的第二个参数修改,而list1本身并没有动。
类似C++中引用传递,如列表,字典,其是将对象真正的传递过去,函数内部的修改也会影响函数外部对象的值。
python中一切都是对象,严格意义上不能说是值传递还是引用传递,我们应该说传不可变对象还是传可变对象
参数
参数类型:
- 必备参数
- 关键字参数
- 默认参数
- 不定长参数
必备参数
必须以正确的顺序传入函数,调用的数量必须和声明时一样。关键字参数
关键字参数和函数调用关系紧密,参数调用使用关键字参数来确定传入的参数值,使用关键字参数允许函数调用时参数的顺序和声明不一致,应为python解释器能够用参数名匹配参数值。
实例:def fun(name,age): print ("name:",name, "age:",age) return nam='wang' ag='12' fun(age=ag,name=nam)
默认参数
调用参数时,默认参数的值如果没有传入,则被认为是默认值。
实例def fun(name,age=22): print ("name:",name, "age:",age) return nam='wang' fun(name=nam)
不定长参数
你可能需要一个函数能处理比当初声明时更多的参数,这些参数叫做不定长参数,和上述两种参数不同,声明时不会命名,基本语法如下:def fun([formal_args,]*var_args_tuple): function_suite return [expression]
加了*的变量名会存放所有未命名的变量参数。
实例:def fun(num,*num1): print(num) for x in num1: print(x) return fun(23) fun(1,2,3,4,5)
匿名函数
语法
lambda [arg1[,arg2,....argn]]:expression
实例
sum=lambda a,b :print(a,b) sum('hello',' python')
return语句
选择性的向调用方返回一个表达式,不带参数值的return语句返回none。
关于python函数形参
c++中直接传递fun(x)函数内可以改变,但是并不影响函数内的值,如果想改变必须使用引用fun(&y),那么python本身就是引用为什么还要区分可变不可变对象呢
不可变对象
实例:
def fun(x): x=1 return x y=10 m=fun(y) print(y, m)
输出
10 1
这就比较直观了,加上之前笔记写的,python string等对象不可变的本质,y本身是引用,你直接改变它,改变的是它的指向,而不是地址空间本身。
fun返回的值,赋予了m,其实是让m指向了一个新的地址空间,而不是你改变了y的旧地址空间。
但是如果你写y=fun(y)
那样y的值就会产生变化,但是仍然是指向改变。
可变对象
那么可变的对象又是什么情况呢,以列表为例,我对函数内赋值影响函数外对象不存在异议,问题是,可变不可变的分类,可变对象内包含一个或多个不可变对象,其底层是如何实现的?
实例:
list1=['a',1,'b','c',4,5] print("before-texting:") print('list1-id:',id(list1)) print('list1[3]-id:',id(list1[3])) list1[3]=6 print('after-texting:') print('list1-id:',id(list1)) print('list1[3]-id:',id(list1[3])) print(list1)
输出
before-texting: list1-id: 1316059963976 list1[3]-id: 1316060171264 after-texting: list1-id: 1316059963976 list1[3]-id: 140737211585728 ['a', 1, 'b', 6, 4, 5]
这个例子很直观,python中以我浅显的理解,不可变对象便是,值变地址变,可变对象是值变地址不变。
可是呢,list这种,它的每一项都有一个地址,我理解为一个父对象有很对子对象,而父对象是地址是不变的,可以任意更换子对象。但是呢,子对象是不可变的,如果改变子对象,那么该子对象就不是原来的子对象了。地址已经改变。
如果以后有什么更深的理解再回来补充。