语法

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这种,它的每一项都有一个地址,我理解为一个父对象有很对子对象,而父对象是地址是不变的,可以任意更换子对象。但是呢,子对象是不可变的,如果改变子对象,那么该子对象就不是原来的子对象了。地址已经改变。
如果以后有什么更深的理解再回来补充。