在运行时在python中运行动态多行代码字符串
如何从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
- 我有一个函数,可以动态生成大量的随机代码片段
- 我希望将此代码传递给变量/字符串,并计算语法/返回代码
- 不能从文件/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“
是三引号字符串的等价项