Rendering of reStructured text is not possible, please install Docutils.

.. contents::

:status: 草稿 ;HuangYi; 10%;

===================
Python函数
===================

在介绍 python 函数之前不得不提的一个概念就是 python 的 callable 。

函数定义
==========

神奇的星号
============

lambda
==========

闭包
==========

装饰器
==========
::
  
  @log
  def test(a, b):
      pass

其中 ``log`` 就是个别人写好的装饰器,作用就是在调用 ``test`` 的前后分别输出个
``enter test`` 和 ``exit test`` ,使用符号 ``@`` 来应用这个装饰器。

用最容易理解的方式来说,装饰器其实很简单,我们给您看上面这段代码的另一种写法,就很清楚了:
::

  def test(a, b):
      pass
  test = log(test)

是的,上面两段代码完全等价!实际上在 python2.4 加上 ``@``
语法之前,大家实际都是用后面这种方法做的。

是不是很简单?但其实也不是那么简单。要从复杂的来讲,它和所谓 AOP
之类的许多概念都扯得上关系。但在 python 中它就是这么简单。

那么这个 ``log`` 应该如何来写呢?
其实有经验的读者从后面这段代码中应该已经能够看出端倪。
``log`` 无非就是接受一个函数作为参数同时返回一个新函数的函数,说起来像绕口令,
不如看代码:
::
  
  def log(func):
      def wrapper(*args, **kw):
          print 'enter', func.__name__
          func(*args, **kw)
          print 'exit', func.__name__
      wrapper.__name__ = func.__name__
      wrapper.__globals__ = func.__globals__
      TODO: 好像还有其他的信息需要偷梁换柱,有待查资料。
      return wrapper

``log`` 里面定义另一个叫 ``wrapper`` 的嵌套函数,它把所有接受到的参数简单地全部传给
``func`` ,并在调用前后输出信息。
最后对 ``wrapper`` 的一些属性进行偷梁换柱之后,就将它返回了,
随后它就可以被当做一个如假包换的 ``func`` 来用了。

函数式编程
============

小结
==========

练习
===========

.. macro:: [[PageComment2(nosmiley=1, notify=1)]]