作用域
作用域又叫命名空间,是一种“不可见字典”,除了全局作用域,每个函数都会创建一个新的作用域,函数内的作用域叫局部变量,全局作用域叫全局变量。
这意味着在函数内部碰到一个变量的时候函数会优先在自己的命名空间里面去寻找。
内置的函数globals返回一个python解析器知道的变量名称的字典,locals返回函数内部作用域变量名称的字典。
变量解析规则
在python的作用域规则里面,创建变量一定会在当前作用域里创建一个变量,但是访问或者修改变量时会先在当前作用域查找变量,没有找到匹配变量的话会一次向上在闭合的作用域里面进行查找。
但在另一个方面,我们在函数内部给全局变量赋值,实际上只是新创建了一个局部变量,隐藏全局变量中的同名变量。
变量生存周期
变量不仅是生存在一个个的命名空间内,他们有自己的生存周期,函数的命名空间随着函数调用开始而开始,结束而销毁。
函数参数
python允许我们向函数传递参数,参数会变成本地变量存在于函数内部。
嵌套函数
Python允许创建嵌套函数。这意味着我们可以在函数里面定义函数而且现有的作用域和变量生存周期依旧适用。
>>>def outer():
x=1
def inter():
print x #1
inter() #2
>>>outer()
1
在#1发生了什么:python解释器需找一个叫x的本地变量,查找失败之后会继续在上层的作用域里面寻找,这个上层的作用域定义在另外一个函数里面。对函数outer来说,变量x是一个本地变量,但是如先前提到的一样,函数inner可以访问封闭的作用域(至少可以读和修改)。
函数是python世界里的一级类对象
显而易见,在python里函数和其他东西一样都是对象。函数可以作为参数传进别的函数。函数也可以作为函数返回值返回。
闭包
>>>def outer():
x = 1
def inner():
print x # 1
return inner
>>>foo = outer()
>>>foo()
1
按变量解析规则来说,在调用inter时应该是找不到x这个参数,但结果确是可以。
嵌套定义在非全局作用域里面的函数能够记住它在被定义的时候它所处的封闭命名空间。这能够通过查看函数的func_closure属性得出结论,这个属性里面包含封闭作用域里面的值
这个特性在python中被称为闭包。
闭包 – 被函数记住的封闭作用域
闭包单独拿出来就是一个非常强大的功能, 在某些方面,你也许会把它当做一个类似于面向对象的技术:outer像是给inner服务的构造器,x像一个私有变量。使用闭包的方式也有很多:你如果熟悉python内置排序方法的参数key,你说不定已经写过一个lambda方法在排序一个列表的列表的时候基于第二个元素而不是第一个。现在你说不定也可以写一个itemgetter方法,接收一个索引值来返回一个完美的函数,传递给排序函数的参数key。
装饰器
装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版函数。
def outer(func):
def inter():
res=func()
return res+1
return inter
def foo():
return 2
f=outer(foo)
print f()
使用 @ 标识符将装饰器应用到函数
def outer(func):
def inter():
res=func()
return res+1
return inter
@outer
def foo():
return 2
print foo()
args and **kwargs
def outer(func):
def inter(*args):
res=func(args[0])
return res+1
return inter
@outer
def foo(n):
return n
print foo(2)
3层
def log(text):
def decorator(func):
def wraper(*args,**kw):
print 'begin call %s %s'%(text,func.__name__)
return func(*args,**kw)
print 'end call %s %s'%(text,func.__name__)
return wraper
return decorator
@log('hello')
def ac():
pass
ac()
一个典型的例子
def log(func):
def wraper(*args,**kw):
print '%s call %s'%(args[0],func.__name__)
return func(*args,**kw)
return wraper
@log
def w(n):
if n=='17:30':exit()
elif n.split(':')[-1]=='30':
os.system('termux-vibrate -d 3000')
os.system("termux-toast '起来走走了'")
time.sleep(60)
return w(time.ctime()[11:16])
else:
time.sleep(15)
return w(time.ctime()[11:16])
原文出自
<http://python.jobbole.com/81683/>
参考文章
<http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819879946007bbf6ad052463ab18034f0254bf355000>