Why I can call 'print' from 'eval'

前端 未结 4 522
夕颜
夕颜 2021-02-06 09:15

For code:

#!/usr/bin/python

src = \"\"\"
print \'!!!\'
import os
\"\"\"

obj = compile(src, \'\', \'exec\')
eval(obj, {\'__builtins__\': False})
相关标签:
4条回答
  • 2021-02-06 09:49

    import calls the global/builtin __import__ function; if there isn't one to be found, import fails.

    print does not rely on any globals to do its work. That is why print works in your example, even though you do not use the available __builtins__.

    0 讨论(0)
  • 2021-02-06 09:53

    print works because you specified 'exec' to the compile function call.

    0 讨论(0)
  • 2021-02-06 09:59

    In your eval the call to import is made successfully however import makes use of the __import__ method in builtins which you have made unavailable in your exec. This is the reason why you are seeing

    ImportError: __import__ not found
    

    print doesn't depend on any builtins so works OK.

    You could pass just __import__ from builtins with something like:

    eval(obj, {'__builtins__' : {'__import__' :__builtins__.__import__}})
    
    0 讨论(0)
  • 2021-02-06 10:00

    The __import__ method is invoked by the import keyword: python.org

    If you want to be able to import a module you need to leave the __import__ method in the builtins:

    src = """
    print '!!!'
    import os
    """
    
    obj = compile(src, '', 'exec')
    eval(obj, {'__builtins__': {'__import__':__builtins__.__import__}})
    
    0 讨论(0)
提交回复
热议问题