多态
在python中,一切皆对象,包括函数也是对象。因为python是动态类型的语言,所以它的多态实现非常容易。比如下面这个例子,一个操作的意义取决于被操作对象的类型。
def func(a,b):
return a * b
test1 = func(12,5)
print(test1) #60
test2 = func('ad',5)
print(test2) #adadadadad
而所谓多态就是对不同类型的对象执行相同的操作,这些操作都能根据自己的类型来正常的运行。
变量作用域
变量的作用域决定了在哪一部分程序可以访问哪个特定的变量。python的作用域一共有4种,分别是:
L(Local)局部作用域
E(Encoding)闭包函数外的函数中
G(Global)全局作用域
B(Built-in)内置作用域(内置函数所在模块的范围)
以L->E->G->B的规则查找,及局部找不到,便会在局部外的局部找,再找不到就去全局了,最后在内置中找。
Python 中只有模块(module),类(class)以及函数(def、lambda)才会引入新的作用域,其它的代码块(如 if/elif/else/、try/except、for/while等)是不会引入新的作用域的,也就是说这些语句内定义的变量,外部也可以访问。
内置作用域是通过一个名为 builtin 的标准模块来实现的,但是这个变量名自身并没有放入内置作用域内,所以必须导入这个文件才能够使用它。
下面我们来说说LEG三种。
x = 66
def func(a):
x = a
print(x)
return x
func(99) #99
print(x) #66
从上例可以看到,第一次输出本地变量覆盖了全局变量,而第二次输出的就是全局变量,因为在调用完func函数之后,x并没有保存起来,随着函数调用的结束,局部变量的X就消失了。
那么如果我想在函数内部修改函数外部声明的值,就需要用到global和nonlocal关键字了。
x = 66
def func():
global x
x = 99
print(x)
func() #99
print(x) #99
关键字global是一个变量命名空间的声明,它告诉python函数打算生成一个或多个全局变量,应用它,就可以在函数内部对全局变量进行引用和修改。如上例,两次的输出都是99。
嵌套函数
x = 88
def func():
x = 99
def func1():
x =77
print(x)
return func1
test = func()
test() #77
如上例所示,在def函数中再嵌套另一个def函数,就是所谓的嵌套函数,而且最终输出的是77。而且本例还有一个特别的地方,前面的例子中,函数的调用结束后,本地作用域就会马上失效,而嵌套作用域在嵌套的函数返回后却仍然有效。
上面这种语言现象叫做闭包:一个能记住嵌套作用域变量值的函数,尽管作用域已经不存在。
def func(x):
k = 10
def func1(n):
return n ** x + k
return func1
test = func(2)
print(test(4)) #26
这里我们可以看出,内嵌的函数func1记住了嵌套作用域内得两个嵌套变量,一个是变量k,一个是参数x,即使后面func1返回并退出。我们通过调用外部的函数func,得到内嵌的函数func1的引用。这种函数嵌套的方法在后面要介绍的装饰器中会经常用到。这种嵌套作用域引用,就是python的函数能够保留状态信息的主要方法了。
那么如何修改嵌套作用域中的变量呢?这个时候就需要nonlocal关键字了!
def func(num):
k = num
def func1(label):
nonlocal k
k += 1
print(label,k)
return func1
f = func(0) #100,100
f('a') #a 1
f('b') #b 2
我们在func1函数中通过nonlocal关键字引用了内嵌作用域中的变量k,那么我们就可以在func1函数中修改他,即使func函数已经退出调用,这个“记忆”依然有效。
http://www.runoob.com/python3/python3-function.html
https://zhuanlan.zhihu.com/c_147297848