69 lines
1.7 KiB
Python
69 lines
1.7 KiB
Python
|
# 我们有时候可以用函数来拓展闭包,使闭包获得类似类的效果
|
|||
|
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变量
|
|||
|
# 不!要!这!么!做!除非有非得这样干的理由,否则别这样搞,老老实实写类,这样的闭包只有类的功能而没有继承多态这些类属性
|