# 我们有时候可以用函数来拓展闭包,使闭包获得类似类的效果 def sample(): n = 0 def func(): print("n=", n) def get_n(): return n def set_n(value): # nonlocal让我们可以访问闭包内的变量,有点类似类里的self nonlocal n n = value # 我们能这么做的本质原因还是因为Python里的万物皆类特性 func.get_n = get_n func.set_n = set_n return func f = sample() f() # 可以看到这里并没有出现代码提示,因为基类没有包含这些东西,它们是在动态编译的时候加入的 f.set_n(10) f() f.get_n() import sys # 比如下面有个类 class ClosureInstance: def __init__(self, locals=None): if locals is None: locals = sys._getframe(1).f_locals self.__dict__.update((key, value) for key, value in locals.items() if callable(value)) def __len__(self): return self.__dict__['__len__']() # 这是用这个类实现的栈实例 def Stack(): items = [] def push(item): items.append(item) def pop(): items.pop() def __len__(): return len(items) return ClosureInstance() # 这是正常的写法 class Stack2: def __init__(self): self.items = [] def push(self, item): self.items.append(item) def pop(self): return self.items.pop() def __len__(self): return len(self.items) # 从执行来说,闭包的写法比正常写法块8%,因为不需要访问额外的self变量 # 不!要!这!么!做!除非有非得这样干的理由,否则别这样搞,老老实实写类,这样的闭包只有类的功能而没有继承多态这些类属性