为 python 3 安装虚拟目录或内存中的 运行 代码
Mounting Virtual Directory, or Running Code in Memory for python 3
我正在制作一个随机批量生成代码的程序,并在给定输入的情况下测试该代码是否生成所需的输出。我想让生成的代码批非常大,比如每批 10,000 个随机生成的文件,所以我想在内存中工作,而不是把它们写入磁盘。我还希望编译器为我完成所有工作,文件一旦创建就作为模块导入,然后在该模块中生成的函数是 运行,并根据所需的输出测试结果。
我发现 Python 有 tempfile.SpooledTemporaryFile(),这将允许我创建和操作一个类似文件的对象,但是一旦创建,我想像访问一个文件一样访问它python 脚本。但是,由于文件在 RAM 中,一旦关闭就会被删除,我正在努力寻找一种方法来做到这一点。我想要的是这样的:
import os, tempfile, importlib, desiredInAndOut, codeGenerator
generatedCodeAsAString = codeGenerator.generateCode()
cwd = os.getcwd()
successfulCode = []
batchSize = int(input(Enter desired batch size:))
runs = 0
while runs < batchSize:
with tempfile.SpooledTemporaryFile(10240, 'w+b', None, None, '\n', '.py', 'tmp', cwd) as stf:
stf.write(generatedCodeAsAsAString.encode())
import tmp #import the newly generated file (that maybe has a 'shortcut' in the cwd? Somehow?)
importlib.invalidate_caches() #make sure the compiler knows that there is a new module for the first time this runs
importlib.reload(tmp) #if the compiler gets smart and re-uses the module from the first import/first iteration of this loop, make sure it reloads/updates it to match the new file that was just created
out = tmp.generatedFunction(desiredInAndOut.GIVEN_INPUT)
if out == desiredInAndOut.DESIRED_OUTPUT:
successfulCode.append(generatedCodeAsAString+'\n'+'#BATCHFILE NO '+str(runs))
runs += 1
print(successfulCode)
尽管我很努力,tmp 文件并没有链接到当前工作目录,所以上面的导入不起作用。我需要找到一种方法将该临时文件的内存地址提供给期望标准“/foo/bar/tmp.py”的导入语句,并确保它将其解释为文件。
由于权限问题,无法直接在计算机上安装虚拟驱动器。如果您知道一种 in-python 方法可以在没有管理员访问计算机的情况下执行类似的操作,我会洗耳恭听。我目前正在探索内置函数 exec 的功能 - 不确定它将如何在 shell 之外响应。我希望它能奏效,但我们拭目以待。
是否有 correct/better 方法来完成我正在尝试的事情?更具体地说,有没有办法将编译器指向内存中存在的文件的方向,以便可以像处理现有文件一样对其进行操作and/or 运行?或者一个 python 格式的字符串,如果我可以 运行 字符串形式,它不一定需要是一个文件。
(如果作为 SpooledTemporaryFile 操作)
和
为我提供了使用内置 exec() 函数制作此解决方案所需的信息:
import sys
from io import StringIO
def main():
GIVEN_INPUT = input('Enter input as an integer:')
code = "def main():\n\tinput = "+GIVEN_INPUT+"\n\tprint(input + 3)\nmain()"
#this code would be randomly generated elsewhere. As is, simply adds 3 to GIVEN_INPUT
old_stdout = sys.stdout
redirected_output = StringIO()
sys.stdout = redirected_output
exec(code)#, sys._getframe(1).f_globals, sys._getframe(1).f_locals)
sys.stdout = old_stdout
print('function completed')
OUTPUT = redirected_output.getvalue().strip()
print(OUTPUT+' is the result of:\n'+ code)
main()
总而言之,exec() 不能 return 我可以看到的值,但它可以打印到 sys.stdout,因此它打印的不是 'returning' 结果结果,我能够通过在生成代码 运行s 时切换出新的 StringIO sys.stdout 来获得它打印的内容,完成后将其切换回正常状态,然后获取内容那个 StringIO 对象。如果它需要采用文件形式,可以使用 tempfile.SpooledTemporaryFile 轻松完成,请参阅上面的第一个 link,但我已经将代码生成为字符串,因此无需转换它进入文件形式先到运行吧。我希望 exec() 没有最大字符数限制,这可能会导致严重问题...
open/run 生成的代码不需要导入语句,并且可以 运行 多次而不会弄乱已安装的虚拟目录,甚至一般的文件对象。
我正在制作一个随机批量生成代码的程序,并在给定输入的情况下测试该代码是否生成所需的输出。我想让生成的代码批非常大,比如每批 10,000 个随机生成的文件,所以我想在内存中工作,而不是把它们写入磁盘。我还希望编译器为我完成所有工作,文件一旦创建就作为模块导入,然后在该模块中生成的函数是 运行,并根据所需的输出测试结果。
我发现 Python 有 tempfile.SpooledTemporaryFile(),这将允许我创建和操作一个类似文件的对象,但是一旦创建,我想像访问一个文件一样访问它python 脚本。但是,由于文件在 RAM 中,一旦关闭就会被删除,我正在努力寻找一种方法来做到这一点。我想要的是这样的:
import os, tempfile, importlib, desiredInAndOut, codeGenerator
generatedCodeAsAString = codeGenerator.generateCode()
cwd = os.getcwd()
successfulCode = []
batchSize = int(input(Enter desired batch size:))
runs = 0
while runs < batchSize:
with tempfile.SpooledTemporaryFile(10240, 'w+b', None, None, '\n', '.py', 'tmp', cwd) as stf:
stf.write(generatedCodeAsAsAString.encode())
import tmp #import the newly generated file (that maybe has a 'shortcut' in the cwd? Somehow?)
importlib.invalidate_caches() #make sure the compiler knows that there is a new module for the first time this runs
importlib.reload(tmp) #if the compiler gets smart and re-uses the module from the first import/first iteration of this loop, make sure it reloads/updates it to match the new file that was just created
out = tmp.generatedFunction(desiredInAndOut.GIVEN_INPUT)
if out == desiredInAndOut.DESIRED_OUTPUT:
successfulCode.append(generatedCodeAsAString+'\n'+'#BATCHFILE NO '+str(runs))
runs += 1
print(successfulCode)
尽管我很努力,tmp 文件并没有链接到当前工作目录,所以上面的导入不起作用。我需要找到一种方法将该临时文件的内存地址提供给期望标准“/foo/bar/tmp.py”的导入语句,并确保它将其解释为文件。
由于权限问题,无法直接在计算机上安装虚拟驱动器。如果您知道一种 in-python 方法可以在没有管理员访问计算机的情况下执行类似的操作,我会洗耳恭听。我目前正在探索内置函数 exec 的功能 - 不确定它将如何在 shell 之外响应。我希望它能奏效,但我们拭目以待。
是否有 correct/better 方法来完成我正在尝试的事情?更具体地说,有没有办法将编译器指向内存中存在的文件的方向,以便可以像处理现有文件一样对其进行操作and/or 运行?或者一个 python 格式的字符串,如果我可以 运行 字符串形式,它不一定需要是一个文件。
(如果作为 SpooledTemporaryFile 操作)
和
为我提供了使用内置 exec() 函数制作此解决方案所需的信息:
import sys
from io import StringIO
def main():
GIVEN_INPUT = input('Enter input as an integer:')
code = "def main():\n\tinput = "+GIVEN_INPUT+"\n\tprint(input + 3)\nmain()"
#this code would be randomly generated elsewhere. As is, simply adds 3 to GIVEN_INPUT
old_stdout = sys.stdout
redirected_output = StringIO()
sys.stdout = redirected_output
exec(code)#, sys._getframe(1).f_globals, sys._getframe(1).f_locals)
sys.stdout = old_stdout
print('function completed')
OUTPUT = redirected_output.getvalue().strip()
print(OUTPUT+' is the result of:\n'+ code)
main()
总而言之,exec() 不能 return 我可以看到的值,但它可以打印到 sys.stdout,因此它打印的不是 'returning' 结果结果,我能够通过在生成代码 运行s 时切换出新的 StringIO sys.stdout 来获得它打印的内容,完成后将其切换回正常状态,然后获取内容那个 StringIO 对象。如果它需要采用文件形式,可以使用 tempfile.SpooledTemporaryFile 轻松完成,请参阅上面的第一个 link,但我已经将代码生成为字符串,因此无需转换它进入文件形式先到运行吧。我希望 exec() 没有最大字符数限制,这可能会导致严重问题...
open/run 生成的代码不需要导入语句,并且可以 运行 多次而不会弄乱已安装的虚拟目录,甚至一般的文件对象。