Python之function

Q1 函数是一等对象

A1

  • 函数可以作为参数传递
  • 可以返回函数
  • 可以赋值给变量
  • 其表现称得上对象

Q2 函数的参数

A2 有位置参数、关键字参数(默认参数)、可变参数(元组参数, *args )以及字典参数( **kargs )。其中元组参数和字典参数名称是我自己取的,网上各种叫法都有,我是根据其数据结构特点取名的。可变参数是指就是一个元组,里面可以存放0个或多个参数,使用*标志。字典参数是在Python3中新加的,其数据结构表现与字典类似,使用**标志。

Q3 传值还是传引用

A3 比较有争议,see: https://www.zhihu.com/question/20591688

我倾向于Python里面没有传值和传引用一说,因为Python没有这两个概念。如果我们从表现的像鸭子即可以认为是鸭子的观点看,对于不可变对象作为函数参数,相当于C++的值传递;对于可变对象作为函数参数,相当于C++的引用传递。但实际上这个理解非常肤浅。这个问题有关Python的名称绑定机制(name binding)。如果按名称绑定的观点看,传进去的就是一块函数外的数据,形参变量名称与这块数据绑定,没有数据被复制,可以认为是引用传递(但实际上又没有指针这个概念,所以讨论到底属于传值还是传引用是没有意义,有意义的地方在于理解参数传递过程以及名称绑定机制)

Python中变量是由名称+数据构成,如果使用一个仅有名称而无数据的变量(或许不该叫变量)会报NameError:name ‘xxx’ is not defined. 数据是有类型的而名称没有类型。名称和数据可以分离,这个过程必然伴随,名称与其它数据结合。而在C/C++这样的语言中名称是不能与数据分离的,名称即数据。

名称与数据的第一次绑定过程,即为名称的定义(名称的初始化)。类似于像a, b = b, a这样的变戏法就是一个名称的重新绑定过程,没有新的数据被创建,因此也不需要另外一个名称。如果从有没有新的数据被创建角度观察Python行为,也许很多疑惑就能解开,比如期待被修改的数据没有被修改,不期待修改的数据被修改。

1
2
3
4
5
6
7
8
9
10
a = [0, [1, 2, 3], 4, 5]
b = a[1] # 没有新数据被创建,修改b也就修改了a
c = {'name': 'jiang', 'gender': 'man', 'index': 0}
d = []
for i in range(5):
c['index'] = i
d.append(c)
print(d) # d内的5个字典都相同,这是为什么呢?这是因为没有新的字典被创建
# 输出
[{'name': 'jiang', 'gender': 'man', 'index': 4}, {'name': 'jiang', 'gender': 'man', 'index': 4}, {'name': 'jiang', 'gender': 'man', 'index': 4}, {'name': 'jiang', 'gender': 'man', 'index': 4}, {'name': 'jiang', 'gender': 'man', 'index': 4}]

Q4 嵌套函数

A4 这是一个比较大的话题,主要讨论变量作用域

------ 本文结束------
赞赏此文?求鼓励,求支持!
  • 本文标题: Python之function
  • 本文作者: Jiang.G.F
  • 创建于: 2019年12月21日 - 23时12分
  • 更新于: 2020年03月03日 - 11时03分
  • 本文链接: https://gfjiangly.github.io/Python/function.html
  • 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!
0%