{人面不知何去处 桃花依旧笑春风}

decorator in python

Posted in Uncategorized by interma on 2013/07/30

依然是在stackoverflow中找到了一个非常详尽的解释,见这里
要点归纳如下:
1,等价语义

def makeitalic(fn):
    def wrapped(str):
        return "<i>" + fn(str) + "</i>"
    return wrapped
@makeitalic
def hello(str):
    return "hello "+str
#等价于hello = makeitalic(hello)
print hello("world") 
#output:<i>hello world</i>

2,基础:函数是对象,所以可以任意赋值;函数可以在另一个函数中定义。=> a function can return another function。
3,关键,为啥要用它呢?
美观&非侵入式的增强函数的行为。
4,来自的同篇帖子的一个实例(配合上*args,**kwargs可以接受任意参数):

def benchmark(func):
    """
    A decorator that prints the time a function takes
    to execute.
    """
    import time
    def wrapper(*args, **kwargs):
        t = time.clock()
        res = func(*args, **kwargs)
        print func.__name__, time.clock()-t
        return res
    return wrapper

def logging(func):
    """
    A decorator that logs the activity of the script.
    (it actually just prints it, but it could be logging!)
    """
    def wrapper(*args, **kwargs):
        res = func(*args, **kwargs)
        print func.__name__, args, kwargs
        return res
    return wrapper

@benchmark
@logging
def reverse_string(string):
    return str(reversed(string))

print reverse_string("Able was I ere I saw Elba")

这里还有。

5,补充:
decorator还可以是类,例如(捎带展示了descriptors)

class Property(object):
    def __init__(self, fget):
        self.fget = fget
    def __get__(self, obj, type):
        if obj is None:
            return self
        return self.fget(obj)
class MyClass(object):
    @Property
    def foo(self):
        return "Foo!"

甚至任何callable的对象都可以?

Tagged with:

yield in python

Posted in Uncategorized by interma on 2013/07/16

缘起至以前那篇python PerformanceTips,对通过yield实现的Generator产生了兴趣。

搜索了一下,stackoverflow上的一个回答介绍的很全面了,简单归纳一下要点:
1,首先明确python中for的语义:顺序迭代,以及iterable的含义。
2,Generators are iterators,但是不提供随机访问(__getitem__())。
3,当含有yield的函数被调用时,函数并没有执行,而是直接返回了一个generator object。
在这个object中猜测一定保存了函数的数据状态(locals and globals)和逻辑运行状态(类似EIP)。
然后每次next()调用时,generator根据当前的数据+逻辑状态生成当前值,同时保持状态为下一次迭代做准备。
4,只有Generators才能迭代一个无限长对象。

另外留几个无关的坑:decorator,descriptor,metaclass,以后要抽空分析一下。

Tagged with:

py3源码[8]-多线程

Posted in Uncategorized by interma on 2013/07/09

1,python中的多线程是系统原生进程,但是受到GIL影响,性能有折损,but not too bad.
知乎上这个问题的扩展讨论:http://www.zhihu.com/question/21219976
2,thread(基础实现,build in,by c),threading(上层保证,std module,by python)
不同平台采用统一接口封装(python/thread_pthread.h,python/thread_nt.h)。
3,默认单进程启动,不采用GIL,避免无误开销。
4,2种调度方法:标准调度(约100条bytecode);阻塞调度(主动退出)。其中GIL是python和os多线程调度之间的桥梁。
5,threading同步/互斥的几个工具:
a,Lock,提供:get/release,互斥锁。
b,RLock,可重入版本Lock。
c,Condition,提供:wait/notify,事件锁。
d,Semaphore,保护n个相同资源,信号量。
e,Event,Condition的简单包装。

Tagged with: