swoole / phpy

Connecting the Python and PHP ecosystems together
Apache License 2.0
542 stars 44 forks source link

feat: eval 支持传入外界变量 #16

Closed caiyili closed 11 months ago

caiyili commented 11 months ago
  1. eval 支持传参数进去(传递的参数会合并到 globals 变量中)
  2. 单元测试及examples增加传参示例
  3. 优化了部分代码:PyRun_ 运行完后,释放input_code内存

PyCore::eval 支持传递参数进入

<?php

$pycode = <<<CODE
square = {
    f'{prefix}{i}': i**2
    for i in range(n)
}
CODE;
$mod2 = PyCore::eval($pycode,['n'=>10, 'prefix'=>'square_']);
printf("mod2->square: %s\n", $mod2->square);

输入如下

mod2->square: {'square_0': 0, 'square_1': 1, 'square_2': 4, 'square_3': 9, 'square_4': 16, 'square_5': 25, 'square_6': 36, 'square_7': 49, 'square_8': 64, 'square_9': 81}
he426100 commented 11 months ago

python有内置的evalexec方法,本身就可以执行动态代码;

$globals = new PyDict(['n'=>10, 'prefix'=>'square_']);
PyCore::exec($pycode, $globals)
 PyCore::print($globals['square'])
{'square_0': 0, 'square_1': 1, 'square_2': 4, 'square_3': 9, 'square_4': 16, 'square_5': 25, 'square_6': 36, 'square_7': 49, 'square_8': 64, 'square_9': 81}
caiyili commented 11 months ago

建议放弃这个功能,python有内置的evalexec方法,本身就可以执行动态代码,搭配 types.ModuleTypecompile就解决了传参和取值的问题,还能玩原生的ast; 或者改个名,不覆盖python内置的eval

function import_from_code($code, $vars = [])
{
    $py = PyCore::import('builtins');
    $module = PyCore::import('types')->ModuleType(uniqid());
    foreach ($vars as $name => $value) {
        $module->$name = $value;
    }
    $py->exec($py->compile($code, '<string>', 'exec'), $module->__dict__);
    return $module;
}

额,这个本身都是调用的python自己的解析,只是你在c语言层面去调用,还是在python语言层面调用的区别,不存在覆盖一说。