簡體   English   中英

如果我使用自定義dict作為函數的全局變量,為什么我不能訪問builtins?

[英]Why can't I access builtins if I use a custom dict as a function's globals?

我有一個像這樣的dict子類:

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

這個類可以與evalexec一起使用而不會出現問題:

>>> 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

globals()dict(globals())或event {'__builtins__': __builtins__}替換MyDict()會使代碼按預期打印<class 'bytearray'>

我不明白這個例外的來源。 誰能解釋這種行為? 為什么它與eval但不與函數對象一起使用?

不是一個完整的答案,但似乎正在發生的是CPython在訪問內置函數時忽略了自定義__getitem__ 它似乎將MyDict視為正常( MyDict類)dict。 如果'__builtins__'鍵實際存在於dict中,那么一切正常:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM