0%

Python函数只能被执行一次

今天有个工作场景是一个注册函数需要执行一次注册任务, 但是该函数仅仅只能在初始化的时候执行一次注册任务, 即该函数只能执行一次.

如何实现这个逻辑?

1
2
3
4
5
6
7
8
9
10
def _register():
print("register ...")


_register()
_register()
_register()

# 多次调用也只能输出一次
>>> register ...

基于类的单例模式

… 略, 想起来再写

基于闭包

我们还可以使用闭包来实现这个逻辑.

维基百科的闭包解释

在计算机科学中,闭包(英语:Closure),又称词法闭包(Lexical Closure)或函数闭包(function closures),是在支持头等函数的编程语言中实现词法绑定的一种技术。闭包在实现上是一个结构体,它存储了一个函数(通常是其入口地址)和一个关联的环境(相当于一个符号查找表)。环境里是若干对符号和值的对应关系,它既要包括约束变量(该函数内部绑定的符号),也要包括自由变量(在函数外部定义但在函数内被引用),有些函数也可能没有自由变量。闭包跟函数最大的不同在于,当捕捉闭包的时候,它的自由变量会在捕捉时被确定,这样即便脱离了捕捉时的上下文,它也能照常运行。捕捉时对于值的处理可以是值拷贝,也可以是名称引用,这通常由语言设计者决定,也可能由用户自行指定(如C++)。

看起来非常的绕, 笔者的简单理解就是函数打包了一份本地环境, 并且通常来将, 闭包的内部变量对于外界是完全隐藏的(但是也有办法访问到)

基于闭包实现上述逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def _register():

# 这里我们在函数内部定义了一个
# 内部变量, 表示该函数是否已经
# 执行过
_loaded = False

def _load():
# 这里写该函数的具体执行逻辑
print("fisrt run, loading ...")
print("loaded")
# 当逻辑被执行一次以后
# 我们需要将设置 _loaded = True
# 用来表示该函数已经被执行过一次
# nonlocal 表示该变量不是本地变量
nonlocal _loaded
_loaded = True

def _run():
if not _loaded:
_load()

return _run

这样我们就实现了一个只能执行一次的函数

执行

1
2
3
f = _register()
f()
f()

可以发现只执行了一次逻辑

1
2
fisrt run, loading ...
loaded