http://blog.csdn.net/ablo_zhou/article/details/5471952
Python 2.4以后,增加了@符号修饰函数对函数进行修饰,python3.0/2.6又增加了对类的修饰。
我现在使用的python版本,支持对class的修饰:
zhouhh@zhouhh-home:~$ python
Python 2.6.4 (r264:75706, Dec 7 2009, 18:45:15)
[GCC 4.4.1] on linux2
Type "help", "copyright", "credits" or "license" for more information.
@修饰符挺像是处理函数或类之前进行预处理。
语法示例:
@dec1
@dec2
def test(arg):
pass
其效果类似于
dec1(dec2(test(arg)))
修饰函数还可以带参数。
@dec1(arg1,arg2)
def test(testarg)
效果类似于
dec1(arg1,arg2)(test(arg))
[]
http://blog.csdn.net/guang11cheng/article/details/51179410
示例1
def minus(f):
print 'minus'
f()
def plus(f):
print 'plus'
f()
def test(a):
if a > 3 :
return plus
else :
return minus
@test(5)
def xxx():
print 'ok'
解释器首先会解释@符号后面的代码,如果如上面的代码类似,那么test(5)将被执行,因为test参数5大于3,所以会返回函数指针plus(可以用C的这个名字来理解),plus将下一行的函数指针xxx当作参数传入,直到执行完成。最后结果将输出‘plus’和‘ok’。 有时候可能是下面这种形式:
示例2
def minus(f):
print 'minus'
f()
@minus
def xxx():
print 'ok'
minus因为本身已经是一个函数指针,所以会直接以xxx作为参数传入,结果会输出‘minus’和‘ok’。
--wjt:是不是说,如果一个函数的入参是另一个函数(实例2),或者一个函数的返回值是另一个带函数参数的函数(实例1),那么这个函数就可以被@。?
即被@的函数,其需要有能力接收的起下一行的函数进入自己的函数体中。?
果真如此。那么装饰器其实并没有什么神秘的,无非就是一个语法:
语法示例:
@dec1
@dec2
def test(arg):
pass
其效果类似于
dec1(dec2(test(arg)))
只需要遵守其语法。实质按上面蓝色字体讲的理解即可。
即装饰器:(1)形式上要求即被@的函数,其需要有能力接收的起下一行的函数进入自己的函数体中;(2)实质执行上效果类似于dec1(dec2(test(arg)))。
下面的例子我分析出的结果正确,说明我的理解到位:
def f1(arg):
print "f1"
rl = arg()
print rl
return rl + "f1"
@f1
def f2(s = ""):
print "f2"
return s + "f2r"
print "start"
D:\Users\wangjiangtao517>python D:\wangjt\zsq.py
f1
f2
f2r
start
--------------------------------------------------------------------
《一步一步详解装饰器》
http://python.jobbole.com/81683/
6. 嵌套函数
Python允许创建嵌套函数。这意味着我们可以在函数里面定义函数而且现有的作用域和变量生存周期依旧适用。
def outer():
x = 1
def inner():
print x # 1
inner() # 2
outer()
1
这个例子有一点儿复杂,但是看起来也还行。想一想在#1发生了什么:python解释器需找一个叫x的本地变量,查找失败之后会继续在上层的作用域里面寻找,这个上层的作用域定义在另外一个函数里面。对函数outer来说,变量x是一个本地变量,但是如先前提到的一样,函数inner可以访问封闭的作用域(至少可以读和修改)。在#2处,我们调用函数inner,非常重要的一点是,inner也仅仅是一个遵循python变量解析规则的变量名,python解释器会优先在outer的作用域里面对变量名inner查找匹配的变量.
7. 函数是python世界里的一级类对象
显而易见,在python里函数和其他东西一样都是对象。
issubclass(int, object) # all objects in Python inherit from a common baseclass
True
def foo():
pass
foo.__class__ # 1
<type 'function'>
issubclass(foo.__class__, object)
True
函数在python里面就是对象,和其他的东西一样,也许这样描述会太学院派太官方了点:在python里,函数只是一些普通的值而已和其他的值一毛一样。这就是说你可以把函数像参数一样传递给其他的函数或者说从函数了里面返回函数!如果你从来没有这么想过,那看看下面这个例子:
def add(x, y):
return x + y
def sub(x, y):
return x - y
def apply(func, x, y): # 1
return func(x, y) # 2
apply(add, 2, 1) # 3
3
apply(sub, 2, 1)
1
把函数当做返回值:
def outer():
def inner():
print "Inside inner"
return inner # 1
foo = outer() #2
>>> foo
<function inner at 0x03912DF0> --- 显示变量 foo 的值(是一个函数)
>>> foo()
Inside inner ---执行了函数inner()
这个例子看起来也许会更加的奇怪。在#1处我把恰好是函数标识符的变量inner作为返回值返回出来。这并没有什么特殊的语法:”把函数inner返回出来,否则它根本不可能会被外界所调用。“还记得变量的生存周期吗?每次函数outer被调用的时候,函数inner都会被重新定义,如果它不被当做变量返回的话,每次执行过后它将不复存在。
在#2处我们捕获返回值 – 函数inner,将它存在一个新的变量foo里。我们能够看到,当对变量foo进行求值,它确实包含函数inner,而且我们能够对他进行调用。初次看起来可能会觉得有点奇怪,但是理解起来并不困难是吧。
8. 闭包
def outer(x):
def inner():
print x # 1
return inner
print1 = outer(1)
print2 = outer(2)
print1()
1
print2()
2
9. 装饰器
装饰器其实就是一个闭包,把一个函数当做参数然后返回一个替代版函数.
def outer(some_func):
def inner():
print "before some_func"
ret = some_func() # 1
return ret + 1
return inner
def foo():
return 1
decorated = outer(foo) # 2
decorated()
before some_func
2
仔细看看上面这个装饰器的例子。我们定义了一个函数outer,它只有一个some_func的参数,在他里面我们定义了一个嵌套的函数inner。inner会打印一串字符串,然后调用some_func,在#1处得到它的返回值。在outer每次调用的时候some_func的值可能会不一样,但是不管some_func的之如何,我们都会调用它。最后,inner返回some_func() + 1的值 – 我们通过调用在#2处存储在变量decorated里面的函数能够看到被打印出来的字符串以及返回值2。
我们可以认为变量decorated是函数foo的一个装饰版本,一个加强版本。事实上如果打算写一个有用的装饰器的话,我们可能会想愿意用装饰版本完全取代原先的函数foo,这样我们总是会得到我们的”加强版“foo。想要达到这个效果,完全不需要学习新的语法,简单地赋值给变量foo就行了:
foo = outer(foo)
foo # doctest: +ELLIPSIS
<function inner at 0x>
现在,任何怎么调用都不会牵扯到原先的函数foo,都会得到新的装饰版本的foo
--------------------------------
《closure(闭包)》
https://www.cnblogs.com/Pierre-de-Ronsard/archive/2012/08/20/2647812.html
closure概念:在一个内部函数中,对外部作用域的变量进行引用,那么内部函数就被认为是closure(闭包)
自由变量:定义在外部函数内,被内部函数引用或者使用的变量为自由变量
函数func_closure 在函数被调用前和调用后使用,效果是一样的
https://segmentfault.com/a/1190000007321972
用比较容易懂的人话说,就是当某个函数被当成对象返回时,夹带了外部变量,就形成了一个闭包。看例子。
def make_printer(msg):
def printer():
print msg # 夹带私货(外部变量)
return printer # 返回的是函数,带私货的函数
printer = make_printer('Foo!')
printer()
支持将函数当成对象使用的编程语言,一般都支持闭包。比如Python, JavaScript。
我个人认为,闭包存在的意义就是它夹带了外部变量(私货),如果它不夹带私货,它和普通的函数就没有任何区别。同一个的函数夹带了不同的私货,就实现了不同的功能。其实你也可以这么理解,闭包和面向接口编程的概念很像,可以把闭包理解成轻量级的接口封装。
ef tag(tag_name):
def add_tag(content):
return "<{0}>{1}</{0}>".format(tag_name, content)
return add_tag
content = 'Hello'
add_tag = tag('a')
print add_tag(content)
# <a>Hello</a>
add_tag = tag('b')
print add_tag(content)
# <b>Hello</b>
在这个例子里,我们想要一个给content加tag的功能,但是具体的tag_name是什么样子的要根据实际需求来定,对外部调用的接口已经确定,就是add_tag(content)。如果按照面向接口方式实现,我们会先把add_tag写成接口,指定其参数和返回类型,然后分别去实现a和b的add_tag。
但是在闭包的概念中,add_tag就是一个函数,它需要tag_name和content两个参数,只不过tag_name这个参数是打包带走的。所以一开始时就可以告诉我怎么打包,然后带走就行。
--------------------
《format函数》
https://www.cnblogs.com/chunlaipiupiupiu/p/7978669.html
python中format函数用于字符串的格式化
通过关键字
1 print('{名字}今天{动作}'.format(名字='陈某某',动作='拍视频'))#通过关键字
2 grade = {'name' : '陈某某', 'fenshu': '59'}
3 print('{name}电工考了{fenshu}'.format(**grade))#通过关键字,可用字典当关键字传入值时,在字典前加**即可
通过位置
1 print('{1}今天{0}'.format('拍视频','陈某某'))#通过位置
2 print('{0}今天{1}'.format('陈某某','拍视频'))
填充和对齐^<>分别表示居中、左对齐、右对齐,后面带宽度
1 print('{:^14}'.format('陈某某'))
2 print('{:>14}'.format('陈某某'))
3 print('{:<14}'.format('陈某某'))
4 print('{:*<14}'.format('陈某某'))
5 print('{:&>14}'.format('陈某某'))#填充和对齐^<>分别表示居中、左对齐、右对齐,后面带宽度
精度和类型f精度常和f一起使用
1 print('{:.1f}'.format(4.234324525254))
2 print('{:.4f}'.format(4.1))
进制转化,b o d x 分别表示二、八、十、十六进制
print('{:b}'.format(250))
print('{:o}'.format(250))
print('{:d}'.format(250))
print('{:x}'.format(250))
千分位分隔符,这种情况只针对与数字
print('{:,}'.format(100000000))
print('{:,}'.format(235445.234235))
--------------------
《案例》
[]
http://blog.sina.com.cn/s/blog_6fe87f870101d9cm.html
'@'符号用作函数修饰符必须出现在函数定义前一行,不允许和函数定义在同一行。也就是说@A def f(): 是非法的。 只可以在模块或类定义层内对函数进行修饰。一个修饰符就是一个函数,它将被修饰的函数做为参数,并返回修饰后的同名函数或其它可调用的东西。
下面不懂:
###################################
def spamrun(fn):
def sayspam(*args):
print "spam,spam,spam"
return sayspam
@spamrun
def useful(a,b):
print a**2+b**2
useful(3,4)
###################################
D:\Users\wangjiangtao517>python D:\wangjt\zsq.py
spam,spam,spam
###################################
def spamrun(fn):
def sayspam(*args):
print "spam,spam,spam"
return sayspam
#@spamrun
def useful(a,b):
print a**2+b**2
useful(3,4)
###################################
D:\Users\wangjiangtao517>python D:\wangjt\zsq.py
25
###################################
def spamrun(fn):
def sayspam(*args):
print "spam,spam,spam"
#return sayspam
#@spamrun
def useful(a,b):
print a**2+b**2
useful(3,4)
###################################
D:\Users\wangjiangtao517>python D:\wangjt\zsq.py
Traceback (most recent call last):
File "D:\wangjt\zsq.py", line 10, in <module>
useful(3,4)
TypeError: 'NoneType' object is not callable
实例
def decorator(fn):
def test(*args):
print "My god!"*3
return fn(*args)
return test
@decorator
def other(a,b):
print a**2+b**2
if __name__=="__main__":
other(4,3)
other(3,4)
结果:
My god!My god!My god!
25
My god!My god!My god!
25
注释掉//print return fn(*args)
结果是:
My god!My god!My god!
My god!My god!My god!
要想使other函数能正常运行,必须加返回值,@decorator是一个statement,会将other函数当作参数传入来执行test方法
------------------
《主线程、子线程主线程、子线程》
用装饰器实现子线程执行10分钟还没返回被主线程kill掉?