zoukankan      html  css  js  c++  java
  • Python中的闭包和装饰器

    理解装饰器需要闭包的知识

    https://segmentfault.com/a/1190000004461404

    理解闭包:

    This value in the enclosing scope is remembered even when the variable goes out of scope or the function itself is removed from the current namespace.

    如何创建闭包(ref:https://www.programiz.com/python-programming/closure):

    The criteria that must be met to create closure in Python are summarized in the following points.

    • We must have a nested function (function inside a function).
    • The nested function must refer to a value defined in the enclosing function.
    • The enclosing function must return the nested function.

    使用闭包的好处和条件:

    Closures can avoid the use of global values and provides some form of data hiding. It can also provide an object oriented solution to the problem.

    When there are few methods (one method in most cases) to be implemented in a class, closures can provide an alternate and more elegant solutions. But when the number of attributes and methods get larger, better implement a class.

    也就是说,当一个类中只有一个方法,那么用闭包来改写这个类更好。但是方法很多就不要用闭包了

    关于装饰器:

    从例子入手:

    def deco_with_param(*args):
      def inner(func):
        print 'start with enclosing args', args
        return func
      return inner

    def deco_without_param(func):
      def inner(*args, **kw):
        print 'start without enclosing ', args, kw
        return func
      return inner

    def decos(*args):
      def inner(func):
        def inner1():
          print 'inner1'
          return func()
        return inner1
      return inner

    print 'bar start'
    @deco_without_param
    def bar():
      print 'In func bar'
    print '-'*10
    bar('bar value')
    print 'bar end'
    print

    print 'may start'
    @decos(123)
    def may():
      print 'In func may'
    print '-'*10
    may()
    print 'may end'
    print

    print 'foo start'
    @deco_with_param(123)
    def foo():
      print 'In func foo'
    print '-'*10
    foo()
    print 'foo end'

    #output

    bar start
    ----------
    start without enclosing ('bar value',) {}
    bar end

    may start
    ----------
    inner1
    In func may
    may end

    foo start
    start with enclosing args (123,)
    ----------
    In func foo
    foo end
    [Finished in 0.1s]

    分析:

    定义bar的时候:bar = deco_without_param(bar) = inner

    调用bar的时候:bar() --> inner()

    定义may的时候:may = decos(123)(may) = inner(may) = inner1

    调用may的时候:may() --> inner1()

    定义foo的时候:foo = deco_with_param(123)(foo) = inner(foo) [所以定义的时候就会输出] = func  

    另外,将 @functools.wraps(func)作为最内层函数的装饰器,可以保证被修饰的函数的__name__保持不变

  • 相关阅读:
    ListView具有多种item布局——实现微信对话列
    CSDN 2013年度博客之星评选——分享几张厦门杭州的美图
    不做旁观者,给博主最有力的支持——博客之星评选,期待您的支持,谢谢路过的朋友投上您宝贵的一票
    Android应用中使用及实现系统“分享”接口
    android手势创建及识别
    JSON数据源的多值参数实现
    葡萄城报表本地设计器
    如何设计带查询条件的报表
    巧用SQL语句补足不完全数据报表
    表格数据分组报表
  • 原文地址:https://www.cnblogs.com/geeklove01/p/8645648.html
Copyright © 2011-2022 走看看