gpt4 book ai didi

Python代码对象、函数和默认参数

转载 作者:行者123 更新时间:2023-12-01 22:58:46 25 4
gpt4 key购买 nike

调查

我有这个程序

def gen_baz():
return 2

def gen_bar(a, b, c=1):
return a, b, c

# ---------- #

# Save the code objects
c1 = gen_bar.__code__
c2 = gen_baz.__code__

dis.dis(gen_bar) # [Disassambly 1]
print(inspect.getsource(gen_bar)) # [Inspect 1]

bar = gen_bar(1, 2) # bar: (1, 2, 1)
baz = gen_baz() # baz: 2
print(f"before: bar={bar}, baz={baz}")

# --------- #

gen_bar.__code__, gen_baz.__code__ = c2, c1 # swap code objects between 2 functions

dis.dis(gen_baz) # [Disassambly 2]
print(inspect.getsource(gen_baz)) # [Inspect 1]

bar = gen_bar() # bar: 2
baz = gen_baz(1, 2) # baz: [Error 1]
print(f"after: bar={bar}, baz={baz}")

这里是反汇编和检查的输出

[Disassembly 1 & 2]
17 0 LOAD_FAST 0 (a)
2 LOAD_FAST 1 (b)
4 LOAD_FAST 2 (c)
6 BUILD_TUPLE 3
8 RETURN_VALUE

[Inspect 1 & 2]
def gen_bar(a, b, c=1):
return a, b, c

[Error 1]
Traceback (most recent call last):
File "C:\Users\something\test.py", line 32, in <module>
baz = gen_baz(1, 2)
TypeError: gen_baz() missing 1 required positional argument: 'c'

问题

  1. 为什么在我交换 baz 和 bar 之间的代码对象后,程序崩溃了?即使它们具有相同的字节码检查结果
  2. python的默认参数存放在哪里?它是否与函数对象一起出现而不是与代码对象一起出现?如果是这样,那么 Inspect 模块如何在第二次检查时给我 c=1

非常感谢!

最佳答案

默认值不存储在 code 对象中。它们直接存储在 function 对象中。

>>> gen_bar.__defaults__
(1,)

正如名称所暗示的那样,getsource 返回的文本来自源代码本身,而不是源代码 生成的对象。 (在对象级别,签名仅由函数尝试从堆栈、全局命名空间等加载的值暗示)

您可以使用 inspect.signature 查看 gen_baz 现在采用三个参数,但它包括默认值,这是不与 code 对象一起传输到 gen_baz

>>> inspect.signature(gen_baz)
<Signature (a, b, c)>

默认参数值的使用隐藏在CALL_FUNCTION 操作码的评估中。给定

def foo(a=1):
return a

可以看到它的字节码都不是

>>> dis.dis(foo)
2 0 LOAD_FAST 0 (a)
2 RETURN_VALUE

无论有无显式参数均不调用

>>> dis.dis('foo(9)')
1 0 LOAD_NAME 0 (foo)
2 LOAD_CONST 0 (9)
4 CALL_FUNCTION 1
6 RETURN_VALUE
>>> dis.dis('foo()')
1 0 LOAD_NAME 0 (foo)
2 CALL_FUNCTION 0
4 RETURN_VALUE

利用函数的 __defaults__ 属性。在该函数中,只是假设一些值可以从局部变量 a 插入堆栈,而不管该变量是如何设置的。在这两个调用中,在使用 CALL_FUNCTION 之前,将一个值简单地加载到堆栈中或不加载到堆栈中。

关于Python代码对象、函数和默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72408304/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com