Wednesday, August 16, 2006

Python 2.5 新增特性 PEP 309 局部函数应用

     函数工具模块包含了函数风格程序的功能。这个工具中一个有用的部分是Partial()函数,即“不完全”函数。在使用函数化风格编写程序的时候你有时候需要构造一些包含参数的外部函数。比如下面的Python 函数f(a,b,c),你可以在其中构建函数g(b,c),这个函数和f(1,b,c)是相同的。我们把这种函数称之为“不完全函数”或者“局部函数”。也就是说你可以只为函数提供部分参数,它同样可以返回一个可操作的对象。下面是一个具有代表性的例子:

import functools

def log (message, subsystem):
    "Write the contents of 'message' to the specified subsystem."
    print '%s: %s' % (subsystem, message)
    ...

server_log = functools.partial(log, subsystem='server')
server_log('Unable to open socket')

下面是另一个例子,这个例中使用了PyGTK包。这个例中有一个动态创建的上下文关联的弹出菜单。在这里open_item()是一个局部函数,这里我们可以只提供第一个参数:
...
class Application:
    def open_item(self, path):
       ...
    def init (self):
        open_func = functools.partial(self.open_item, item_path)
        popup_menu.append( ("Open", open_func, 1) )

函数工具中的另一个有用的函数是update_wrapper(wrapper, wrapped)函数。它可以帮助你写出非常好的“装饰器”。update_wrapper可以将一个封装中的名称、模型和文档对象完全复制到另一个封装中。这很容易理解,看下面的例子:
def my_decorator(f):
    def wrapper(*args, **kwds):
        print 'Calling decorated function'
        return f(*args, **kwds)
    functools.update_wrapper(wrapper, f)
    return wrapper

其中的wrapper()函数是一个装饰器,你可以用它来赋值其他函数的信息,下面的例子是上面例子的一个替代版本:
def my_decorator(f):
    @functools.wraps(f)
    def wrapper(*args, **kwds):
        print 'Calling decorated function'
        return f(*args, **kwds)
    return wrapper

No comments: