Python:封装在经常调用的函数中

标签 python performance encapsulation

我有这个 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 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)行的编译常量代码对象,即它不编译f2'一遍又一遍的 body 。

关于Python:封装在经常调用的函数中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48585807/

相关文章:

python - 使用python和win32com取消Excel的关闭事件

javascript - document.getElementbyID 与变量声明和删除性能

java - 程序执行是非顺序的。为什么?

python - 如何通过 DataFrame 压扁 Pandas group?

python - 使用文件将环境变量加载到 Google Cloud Build

python - 将 mssql 空间字段导入 geopandas/shapely 几何图形

python - 为什么显式调用魔术方法比 "sugared"语法慢?

c++ - 如何将字符串解析为 C++ typename?

c++ - 这里是否违反了封装的概念?

java - 如果封装度太低,怎么可能获得不必要的紧密耦合