gpt4 book ai didi

python - 如果我使用自定义字典作为函数的全局变量,为什么我不能访问内置函数?

转载 作者:太空狗 更新时间:2023-10-29 21:57:48 26 4
gpt4 key购买 nike

我有一个 dict像这样的子类:

class MyDict(dict):
def __getitem__(self, name):
return globals()[name]

此类可与 eval 一起使用和 exec 没有问题:

>>> eval('bytearray', MyDict())
<class 'bytearray'>
>>> exec('print(bytearray)', MyDict())
<class 'bytearray'>

但是如果我用 types.FunctionType 实例化一个函数对象构造函数,该函数不能访问任何内置函数:

import types

func = lambda: bytearray
func_copy = types.FunctionType(func.__code__,
MyDict(),
func.__name__,
func.__defaults__,
func.__closure__)

print(func_copy())
# Traceback (most recent call last):
# File "untitled.py", line 16, in <module>
# print(func_copy())
# File "untitled.py", line 8, in <lambda>
# func = lambda: bytearray
# NameError: name 'bytearray' is not defined

替换 MyDict()globals()dict(globals())或事件 {'__builtins__': __builtins__}使代码打印 <class 'bytearray'>正如预期的那样。

我不明白这个异常是从哪里来的。谁能解释这种行为?为什么它适用于 eval但不是函数对象?

最佳答案

不是一个完整的答案,但似乎正在发生的是 CPython 在访问内置函数时忽略了自定义 __getitem__。它似乎把 MyDict 当作一个普通的(不是子类的)dict。如果 '__builtins__' 键实际上存在于字典中,那么一切正常:

class MyDict(dict):
def __getitem__(self, name):
return globals()[name]


import types

globs = MyDict()
globs['__builtins__'] = __builtins__

func = lambda: bytearray
func_copy = types.FunctionType(func.__code__,
globs,
func.__name__,
func.__defaults__,
func.__closure__)

print(func_copy())
# output: <class 'bytearray'>

问题仍然是为什么这只发生在 FunctionType 上,而不发生在 evalexec 上。

关于python - 如果我使用自定义字典作为函数的全局变量,为什么我不能访问内置函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50604799/

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