Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在运行时在python中运行动态多行代码字符串_Python_Python 3.x_Dynamic - Fatal编程技术网

在运行时在python中运行动态多行代码字符串

在运行时在python中运行动态多行代码字符串,python,python-3.x,dynamic,Python,Python 3.x,Dynamic,如何从python内部运行多行代码字符串,此外,该字符串在运行时生成并存储在字符串或数组中 背景 我有一个函数,可以动态生成大量的随机代码片段 我希望将此代码传递给变量/字符串,并计算语法/返回代码 不能从文件/api请求等导入代码,因为重点是高吞吐量和速度 示例 # my function returns random code snippets myCode = myRandomCodeGenerator() # I wish to perform some in fight vali

如何从python内部运行多行代码字符串,此外,该字符串在运行时生成并存储在字符串或数组中

背景

  • 我有一个函数,可以动态生成大量的随机代码片段
  • 我希望将此代码传递给变量/字符串,并计算语法/返回代码
  • 不能从文件/api请求等导入代码,因为重点是高吞吐量和速度
示例

# my function returns random code snippets
myCode = myRandomCodeGenerator()

# I wish to perform some in fight validation (ideally RC or syntax)
someTestingFunction(myCode)
我迄今为止的尝试

我见过下面这样的解决方案,但是因为我的代码是动态生成的,所以我的格式有问题。我已尝试在字符串中生成\n和\r或添加“”,以弥补运气不佳

code = """
def multiply(x,y):
    return x*y

print('Multiply of 2 and 3 is: ',multiply(2,3))
"""

exec(code)
我还尝试过在字符串上使用
call
函数来产生类似的格式问题

到目前为止,我所能做的最好的事情就是执行一行一行的语法检查,并一次向它提供一行,如下所示

import codeop
def is_valid_code(line):
    try:
        codeop.compile_command(line)
    except SyntaxError:
        return False
    else:
        return True

我想可能有一些语法技巧可以用来保留缩进和返回的格式。我也知道在运行时生成动态代码的风险,并且在函数中有一个允许的术语过滤器。

尝试使用“\t”而不是为缩进放置制表符和空格,这样可以保留格式

code = """
def multiply(x,y):
\t return x*y

print('Multiply of 2 and 3 is: ',multiply(2,3))
"""
exec(code)

尝试使用“\t”而不是为缩进放置制表符和空格,这样可以保留格式

code = """
def multiply(x,y):
\t return x*y

print('Multiply of 2 and 3 is: ',multiply(2,3))
"""
exec(code)

乔兰·比斯利回答了这个问题

本质上,我的问题是我在
\n
之后添加了一个空格,因为其他编译器会感到困惑,但是python会考虑到这一点。 因此,如果在def语句中的返回回车后添加空格,将产生语法错误


我保留了这封信,以防其他人遇到类似问题。

这个问题由Joran Beasley回答

本质上,我的问题是我在
\n
之后添加了一个空格,因为其他编译器会感到困惑,但是python会考虑到这一点。 因此,如果在def语句中的返回回车后添加空格,将产生语法错误


我保留了这一点,以防其他人遇到类似问题。

另一种代替
eval
exec
的方法是先编译代码,然后执行它:

例如:

import contextlib,sys
from io import StringIO 
@contextlib.contextmanager
def stdoutIO(stdout=None):
    old = sys.stdout
    if stdout is None:
        stdout = StringIO()
    sys.stdout = stdout
    yield stdout
    sys.stdout = old


def run_code(override_kale_blocks):
    compiled123 = []
    for b123 in override_kale_blocks:
        compiled123.append(compile(b123,"<string>","exec"))
    
    with stdoutIO() as s:
        for c123 in compiled123:
            exec(c123)
    return s.getvalue()
    


block0='''
import time
a=5
b=6
b=a+b
'''
block1='''
b=a+b
'''
block2="print(b)"
blocksleep='''
print('startsleep')
time.sleep(1)
print('donesleep')
'''
pc  = (block0,blocksleep,block1,block2)
cb = []
print('before')
output= run_code(pc)
print(output)
print('after')
print("Hello World!\n")
import contextlib,sys
从io导入StringIO
@contextlib.contextmanager
def标准输出(标准输出=无):
old=sys.stdout
如果标准输出为无:
stdout=StringIO()
sys.stdout=stdout
产量标准
sys.stdout=old
def运行代码(覆盖kale块):
compiled123=[]
对于覆盖块中的b123:
compiled123.append(compile(b123,“,“exec”))
将stdoutIO()作为s:
对于compiled123中的c123:
行政主任(c123)
返回s.getvalue()
块0=''
导入时间
a=5
b=6
b=a+b
'''
区块1=''
b=a+b
'''
block2=“打印(b)”
块睡眠=“”
打印('startsleep')
时间。睡眠(1)
打印('donesleep')
'''
pc=(块0,块睡眠,块1,块2)
cb=[]
打印('before')
输出=运行代码(pc)
打印(输出)
打印('after')
打印(“你好,世界!\n”)
资料来源:
另一种代替
eval
exec
的方法是先编译代码,然后再执行:

例如:

import contextlib,sys
from io import StringIO 
@contextlib.contextmanager
def stdoutIO(stdout=None):
    old = sys.stdout
    if stdout is None:
        stdout = StringIO()
    sys.stdout = stdout
    yield stdout
    sys.stdout = old


def run_code(override_kale_blocks):
    compiled123 = []
    for b123 in override_kale_blocks:
        compiled123.append(compile(b123,"<string>","exec"))
    
    with stdoutIO() as s:
        for c123 in compiled123:
            exec(c123)
    return s.getvalue()
    


block0='''
import time
a=5
b=6
b=a+b
'''
block1='''
b=a+b
'''
block2="print(b)"
blocksleep='''
print('startsleep')
time.sleep(1)
print('donesleep')
'''
pc  = (block0,blocksleep,block1,block2)
cb = []
print('before')
output= run_code(pc)
print(output)
print('after')
print("Hello World!\n")
import contextlib,sys
从io导入StringIO
@contextlib.contextmanager
def标准输出(标准输出=无):
old=sys.stdout
如果标准输出为无:
stdout=StringIO()
sys.stdout=stdout
产量标准
sys.stdout=old
def运行代码(覆盖kale块):
compiled123=[]
对于覆盖块中的b123:
compiled123.append(compile(b123,“,“exec”))
将stdoutIO()作为s:
对于compiled123中的c123:
行政主任(c123)
返回s.getvalue()
块0=''
导入时间
a=5
b=6
b=a+b
'''
区块1=''
b=a+b
'''
block2=“打印(b)”
块睡眠=“”
打印('startsleep')
时间。睡眠(1)
打印('donesleep')
'''
pc=(块0,块睡眠,块1,块2)
cb=[]
打印('before')
输出=运行代码(pc)
打印(输出)
打印('after')
打印(“你好,世界!\n”)
资料来源:

如果无法正确格式化间距,您希望它做什么?间距对python非常重要…我认为这是一个XY问题…在这里,您使用X来解决Y,但有一个更好的方法来解决Y…还有您认为您已经准备好的任何安全措施…如果这是用户输入数据,您将在有人真的希望我同意,有没有办法在动态生成时保留间距/缩进?我列出的exec示例在手动输入时效果很好。它(
exec
)不会修改空格…所以生成具有有效间距的代码
exec(“def multiply(x,y):\n返回x*y\n print('2和3的乘积是:'),multiply(2,3))\n“
是上面三重引号字符串的等价物,没有三重引号。我在上面的注释或答案中没有看到明显的uin,但您知道在代码字符串中使用
\n
特殊序列将生成换行符,不是吗?只需在行尾添加
\n
对于多行脚本,如果不能正确格式化间距,您希望它做什么…?间距对python非常重要…我认为这是一个XY问题…在这里,您使用X来解决Y,但是有一个更好的方法来解决Y…还有您认为有什么安全措施…如果这是您需要的用户输入数据,那么如果有人真的想要我同意,有没有办法在动态生成时保留间距/缩进?我列出的exec示例在手动输入时效果很好。它(
exec
)不会修改空格…所以生成具有有效间距的代码
exec(“def multiply(x,y):\n返回x*y\n打印('2和3的乘法是:',乘法(2,3))\n“
是三引号字符串的等价项