C Python而:上下文中运行的Python code [英] C Python: Running Python code within a context

查看:149
本文介绍了C Python而:上下文中运行的Python code的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Python的C API函数 PyEval_Eval code 让你执行编译的Python code。我想执行Python code 就好像它是一个函数的范围内执行块,所以它有它自己的局部变量不影响全局状态的字典。

The Python C API function PyEval_EvalCode let's you execute compiled Python code. I want to execute a block of Python code as if it were executing within the scope of a function, so that it has its own dictionary of local variables which don't affect the global state.

这似乎很容易做到,因为 PyEval_Eval code 让你提供一个全局和局部字典:

This seems easy enough to do, since PyEval_EvalCode lets you provide a Global and Local dictionary:

的PyObject * PyEval_Eval code(PY codeObject的*合作,*的PyObject全局,*的PyObject当地人)

我遇到的问题与Python的查找变量名的事。请看下面的code,我执行与 PyEval_Eval code

The problem I run into has to do with how Python looks up variable names. Consider the following code, that I execute with PyEval_EvalCode:

myvar = 300
def func():
    return myvar

func()

这个简单的code实际上引发错误,因为Python是找不到变量 MYVAR 从FUNC C>。尽管 MYVAR 是在外部范围的本地字典,Python不其复制到本地字典中的内部范围。这样做的原因如下:

This simple code actually raises an error, because Python is unable to find the variable myvar from within func. Even though myvar is in the local dictionary in the outer scope, Python doesn't copy it into the local dictionary in the inner scope. The reason for this is as follows:

每当Python中查找一个变量名,首先它检查当地人,然后它再检查全局,最后它检查建宏。在模块范围当地人全局是相同的字典对象。因此,声明 X = 5 在模块范围将会把 X 中的当地人词典,这也是全局字典。现在,在功能,需要查找模块范围 X 不会找到 X 的函数范围内<定义code>当地人,因为Python不模块范围当地人复制到功能范围的本地人。但是,这通常是没有问题的,因为它可以找到 X 全局

Whenever Python looks up a variable name, first it checks locals, then it checks globals, and finally it checks builtins. At module scope, locals and globals are the SAME dictionary object. So the statement x = 5 at module scope will place x in the the locals dictionary, which is also the globals dictionary. Now, a function defined at module scope which needs to lookup x won't find x within the function-scope locals, because Python doesn't copy module-scope locals into function-scope locals. But this normally isn't a problem, because it can find x in globals.

x = 5
def foo():
   print(x) # This works because 'x' in globals() == True

它只与嵌套的功能,即Python的似乎外范围当地人复制到内范围本地人。 (这似乎也是这样做的懒惰,只有当它们在内部范围内必要的。)

It's only with nested functions, that Python seems to copy outer-scope locals into inner-scope locals. (It also seems to do so lazily, only if they are needed within the inner scope.)

def foo():
   x = 5
   def bar():
      print(x) # Now 'x' in locals() == True
   bar()

结果
所以,这一切的结果是,在的执行code当模块范围的,你必须确保你的全局字典和本地字典是同一个对象,否则模块范围的功能赢得了 T为能够访问模块范围变量。


So the result of all this is that, when executing code at module scope, you HAVE to make sure that your global dictionary and local dictionary are the SAME object, otherwise module-scope functions won't be able to access module-scope variables.

但在我而言,我不希望全局字典和本地字典是相同的。所以,我需要一些方法来告诉大家,我在函数范围内执行code Python的跨preTER。是否有某种方式做到这一点?我看了看 PyCompileFlags 以及额外的参数 PyEval_Eval codeEX 并不能找到任何方式要这样做。

But in my case, I don't WANT the global dictionary and local dictionary to be the same. So I need some way to tell the Python interpreter that I am executing code at function scope. Is there some way to do this? I looked at the PyCompileFlags as well as the additional arguments to PyEval_EvalCodeEx and can't find any way to do this.

推荐答案

Python不实际复制外范围当地人到内范围的当地人;对于 当地人的文档 规定:

Python doesn't actually copy outer-scope locals into inner-scope locals; the documentation for locals states:

自由变量被当地人()被调用时在功能块类块返回,但不是。

Free variables are returned by locals() when it is called in function blocks, but not in class blocks.

下面的免费变量是指由一个嵌套函数关闭了变数。这是一个很重要的区别。

Here "free" variables refers to variables closed over by a nested function. It's an important distinction.

您的具体情况,最简单的解决方法是刚刚通过的相同的字典对象全局当地人

The simplest fix for your situation is just to pass the same dict object as globals and locals:

code = """
myvar = 300
def func():
    return myvar

func()
"""
d = {}
eval(compile(code, "<str>", "exec"), d, d)

另外,你可以用你的code的作用,并从编译对象提取它:

Otherwise, you can wrap your code in a function and extract it from the compiled object:

s = 'def outer():\n    ' + '\n    '.join(code.strip().split('\n'))
exec(compile(s, '<str>', 'exec').co_consts[0], {}, {})

这篇关于C Python而:上下文中运行的Python code的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆