• [持续更新]Python 笔记


    本文以 Python 2.7 为基础。

    lambda 函数实现递归

    方法一:传递一个 self 参数

    求阶乘:

    1 frac = lambda self, x: self(self, x - 1) * x if x > 1 else 1
    2 print frac(frac, 4)

    方法二(匿名函数实现递归):将一个完整的 lambda 函数体作为参数

    求最大公因数:

    (lambda a, b, s = lambda a, b, f: f(b, a % b, f) if b else a: s(a, b, s))(3, 5)

    由此可以用一行代码求多个数的最小公倍数:

    (lambda *args: reduce(lambda a, b: a * b / (lambda a, b, s = lambda a, b, f: f(b, a % b, f) if b else a: s(a, b, s))(a, b), args))(2, 3, 4)

    Decorator

    Decorator,修饰器,顾名思义就是对函数进行「修饰」(即添加一些功能)的语法糖。一个简单的例子如下:

    1 def transform(func):
    2     print 'Hello, '
    3     return func
    4 
    5 @transform
    6 def world():
    7     print 'World!'
    8 
    9 world()

    通过在 world 函数的定义之前添加一句 @transform 完成 transform 函数对 world 函数的修饰,上面这段程序的运行结果是输出 'Hello, World!'

    事实上,@transform 一句被解释为 world = transform(world),从中可以看出:

    1. transform 函数的返回值应该是一个函数;

    2. 在 @transform 时 transform 函数被执行了一次;

    3. world 函数将会成为一个新的函数的实例(尽管在这个例子中它还是它本身)。

    那么对上面的代码的实质有了一些解释:

    1. 'Hello, '这部分实际上在 world 函数定义完成时输出,所以即使不调用 world 函数也会输出 'Hello, ' 这部分;

    2. 'World!'这部分在调用 world 函数时输出;

    3. 由于 world 函数本身的内容并没有发生变化,所以如果第二次调用 world,将只是输出 'World!'

    接下来看被修饰的函数被替换为新的函数实例的情况:

     1 def transform(func):
     2     def inside():
     3         print 'Hello,',
     4         func()
     5     return inside
     6 
     7 
     8 @transform
     9 def world():
    10     print 'World!'
    11 
    12 world()

    对这段代码的解释:

    1. 由于 transform 函数内部只是定义了另外一个函数而没有执行其他实际(输出)操作,所以 @transform 一句执行时并没有任何输出;

    2. world 函数在 @transform 一句执行之后内容被替换为了 inside 函数的内容,而 inside 函数实际上执行了两部分内容:第一步是输出 'Hello, ',第二步是执行原来的 world 函数的内容,即输出 'World!'。所以新的 world 函数实际上也也是执行了这样两个输出;

    3. 由于 world 函数的实际内容已经发生变化,所以如果第二次执行 world 函数输出的也是 'Hello, World!'

    Decorator 的好处:

    「将函数的约束放置于接口处,使意图更加明了,同时又不增加调用者的负担。」(引用自http://blog.csdn.net/thy38/article/details/4471421  Python Decorator 的带参数用法也请参考此文。)


    2017年8月3日更新:

    带参数的 decorator:

    def wrapper(arg):
      def decorator(func):
    print arg
    return func return decorator

    @wrapper("hello ")
    def func():
    print "world"

    Multiple decorators apply in nested fashion, for example:

    @f1(arg)
    @f2
    def func(): pass

    is roughly equivalent to

    def func(): pass
    func = f1(arg)(f2(func))

    实际应用

    Flask 中的 Flask.route()

    def route(self, rule, **options):
            def decorator(f):
                endpoint = options.pop('endpoint', None)
                self.add_url_rule(rule, endpoint, f, **options)
                return f
            return decorator

    形如 @app.route 这样的写法实际上只是调用了 add_url_rule 方法。

    实现 Multimethod

    http://www.artima.com/weblogs/viewpost.jsp?thread=101605

    本质

    Decorator 的本质是 higher-order function call 的语法糖,其本身并没有什么强大之处, 只不过为函数变换提供了直观简单的语法结构。

  • 相关阅读:
    redis 秒杀设计,常用命令
    wamp下配置多域名和访问路径的方法
    git commit 因执行yarn , npm,报错推送不了
    taro bug--小程序报错Error: 未找到入口 sitemap.json 文件,或者文件读取失败,请检查后重新编译。
    vscode引用相对路径,scss时路径报错问题解决
    space-between与space-around的区别
    Android可设置任意高度的TextView,如:设置0.5px设置0.1px等等
    Android可以打开微信支付,但是没法调起小程序支付
    dask
    Joblib-lightweight piplining tool
  • 原文地址:https://www.cnblogs.com/lsdsjy/p/4305340.html
Copyright © 2020-2023  润新知