评估文本并从IFF中“产生”,它涉及对生成器函数的调用

时间:2018-11-24 14:00:30

标签: python python-3.x

我正在用C编写游戏引擎,可以选择在每一帧调用嵌入式Python解释器,从而可以修改游戏状态。它启动一个Python函数,该函数循环,等待用户通过命名的Unix管道来输入,并eval输入。如果输入“ break”,它将退出循环并恢复C程序。一切都很好,但我希望能够调用一个advance_frame()函数,该函数暂停python程序,并在同一位置的下一帧继续执行,因此我使该函数由C程序调用生成器,并调用其send方法,而不是调用函数本身。

我知道“ yield from”可以创建一种函数堆栈,当遇到“ yield”时这些函数都将被挂起,因此在输入循环中我尝试了yield from eval(input_string, locals())。问题是我想输入"advance_frame()",它会yield,但我也想打电话,说"print("hello world")",这不会产生(这是很好,因为我不希望它将控制权从python传递出去。但是,如果对eval的调用以yield from开头,则调用print之类的普通函数就是TypeError: 'NoneType' object is not iterable

有没有解决的办法?基本上我需要像yield from <expression> if <expression calls a generator function> else <expression>

这样的逻辑

我知道对于函数调用,我可以做类似

的操作
import inspect
if inspect.isgeneratorfunction(myfunction):
    yield from myfunction()
else:
    myfunction()

但是问题是我正在使用用户输入的表达式(可能包括函数调用),而不是函数对象。我能看到的唯一解决方案是使用yield from,并捕获并忽略如果表达式不屈服而引发的TypeError,但这似乎是错误的事情。

整个代码如下:

def while_eval():

    # Get game state from caller in C:
    state_ptr = yield
    ctypes.pythonapi.PyCapsule_GetPointer.argtypes=[ctypes.py_object, ctypes.c_char_p]
    ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.POINTER(structdef.struct_status_struct)
    state_ptr=ctypes.pythonapi.PyCapsule_GetPointer(capsule,ctypes.c_char_p(None))

    print("Handing control to the python interpreter, reading from the pipe pypipe")
    try:
        pipe = open('pypipe')
    except Exception as e:
        print(e)
        return

    while True:
        try:
            instr = pipe.readline()
            if instr == 'break\n':
                print("Leaving exec loop")
                # Return to C program:
                yield
            else:
                #yield from eval(instr,locals()) #Doesn't work for non yielding functions or statements like state_ptr=0
                #eval(instr,locals()) # Doesn't work for yielding functions or statements like state_ptr=0
                exec(instr,locals()) # Doesn't work for yielding functions
        except Exception as e: print(e)

0 个答案:

没有答案