Python: 封装在经常调用的函数中
Python: encapsulation in frequently called function
我有这个 Python 3 伪代码:
def f1():
a, b, c, d, e, f = some_other_fn()
if (condition):
f2(a, b, c, d, e, f)
def f2(a, b, c, d, e, f):
complex_set_of_operations_with(a, b, c, d, e, f)
for i in range(1000):
f(1)
现在,我对 f2()
中的长签名和重复感到有点恼火,想将其封装到 f1()
:
def f1():
def f2():
complex_set_of_operations_with(a, b, c, d, e, f)
a, b, c, d, e, f = some_other_fn()
if (condition):
f2()
for i in range(1000):
f(1)
现在,我的问题是:如果我 运行 f1()
一千次,解释器是否必须解析 f2()
一千次,或者它是否足够聪明来创建一个可重用的参考资料?
Python懒惰评价。它只会在实际需要时才进行评估。
https://swizec.com/blog/python-and-lazy-evaluation/swizec/5148
Lazy evaluation python
让我们看看(使用我手头正好有的Python 3.5)。我们将使用 dis 模块反汇编函数并检查其字节码:
>>> def f1():
... def f2():
... complex_set_of_operations_with(a, b, c, d, e, f)
... a, b, c, d, e, f = some_other_fn()
... if (condition):
... f2()
...
>>> import dis
>>> dis.dis(f1)
2 0 LOAD_CLOSURE 0 (a)
3 LOAD_CLOSURE 1 (b)
6 LOAD_CLOSURE 2 (c)
9 LOAD_CLOSURE 3 (d)
12 LOAD_CLOSURE 4 (e)
15 LOAD_CLOSURE 5 (f)
18 BUILD_TUPLE 6
21 LOAD_CONST 1 (<code object f2 at 0x7f5d58589e40, file "<stdin>", line 2>)
24 LOAD_CONST 2 ('f1.<locals>.f2')
27 MAKE_CLOSURE 0
30 STORE_FAST 0 (f2)
... # the rest is omitted for brevity
在运行时,Python解释器将这些原始字节码指令一条一条解释。 documentation.
中解释了这些说明
如上例的最后四个指令所示,Python 确实每次都构建内部函数(并将其存储在名称 f2
下),但它似乎通过加载 f2
(21 LOAD_CONST
)行的预编译常量 code object,即它不会反复编译 f2
的主体再来一遍。
我有这个 Python 3 伪代码:
def f1():
a, b, c, d, e, f = some_other_fn()
if (condition):
f2(a, b, c, d, e, f)
def f2(a, b, c, d, e, f):
complex_set_of_operations_with(a, b, c, d, e, f)
for i in range(1000):
f(1)
现在,我对 f2()
中的长签名和重复感到有点恼火,想将其封装到 f1()
:
def f1():
def f2():
complex_set_of_operations_with(a, b, c, d, e, f)
a, b, c, d, e, f = some_other_fn()
if (condition):
f2()
for i in range(1000):
f(1)
现在,我的问题是:如果我 运行 f1()
一千次,解释器是否必须解析 f2()
一千次,或者它是否足够聪明来创建一个可重用的参考资料?
Python懒惰评价。它只会在实际需要时才进行评估。
https://swizec.com/blog/python-and-lazy-evaluation/swizec/5148
Lazy evaluation python
让我们看看(使用我手头正好有的Python 3.5)。我们将使用 dis 模块反汇编函数并检查其字节码:
>>> def f1():
... def f2():
... complex_set_of_operations_with(a, b, c, d, e, f)
... a, b, c, d, e, f = some_other_fn()
... if (condition):
... f2()
...
>>> import dis
>>> dis.dis(f1)
2 0 LOAD_CLOSURE 0 (a)
3 LOAD_CLOSURE 1 (b)
6 LOAD_CLOSURE 2 (c)
9 LOAD_CLOSURE 3 (d)
12 LOAD_CLOSURE 4 (e)
15 LOAD_CLOSURE 5 (f)
18 BUILD_TUPLE 6
21 LOAD_CONST 1 (<code object f2 at 0x7f5d58589e40, file "<stdin>", line 2>)
24 LOAD_CONST 2 ('f1.<locals>.f2')
27 MAKE_CLOSURE 0
30 STORE_FAST 0 (f2)
... # the rest is omitted for brevity
在运行时,Python解释器将这些原始字节码指令一条一条解释。 documentation.
中解释了这些说明如上例的最后四个指令所示,Python 确实每次都构建内部函数(并将其存储在名称 f2
下),但它似乎通过加载 f2
(21 LOAD_CONST
)行的预编译常量 code object,即它不会反复编译 f2
的主体再来一遍。