如何在另一个目录中运行python脚本,而不将脚本写入磁盘?

如何在另一个目录中运行python脚本,而不将脚本写入磁盘?,python,terminal,subprocess,Python,Terminal,Subprocess,假设我有两个python脚本methods.py和driver.py。 methods.py具有其中定义的所有方法,并且driver.py在运行它时执行所需的作业 假设我在一个主目录中,有两个文件driver.py和methods.py,我在主目录中有n子目录,名为subdir1,subdir2,…,subdirn。所有这些子目录都有文件作为driver.py的输入 我想做的是在所有这些子目录中运行driver.py,并从中获取我的输出,而不将driver.py写入磁盘 我该怎么做? 目前,我正

假设我有两个python脚本
methods.py
driver.py
methods.py
具有其中定义的所有方法,并且
driver.py
在运行它时执行所需的作业

假设我在一个主目录中,有两个文件
driver.py
methods.py
,我在主目录中有
n
子目录,名为
subdir1
subdir2
,…,
subdirn
。所有这些子目录都有文件作为
driver.py
的输入

我想做的是在所有这些子目录中运行
driver.py
,并从中获取我的输出,而不将
driver.py
写入磁盘

我该怎么做? 目前,我正在使用子流程模块

  • 将driver.py和methods.py复制到子目录
  • 运行它们
  • 复制部分很简单:

    import subprocess
    
    for i in range(n):
      cmd = "cp methods.py driver.py subdir"+str(i)
      p = subprocess.Popen(cmd, shell=True)
      p.wait()
    
    #once every subdirectory has driver.py and methods.py, start running these codes 
    
    for i in range(n):
      cmd = "cd subdir" + str(i) +" && python driver.py"
      p = subprocess.Popen(cmd, shell=True)
      p.wait()
    

    有没有办法在不占用磁盘空间的情况下执行上述操作?

    您可以使用pythons os.chdir()函数更改当前工作目录:

    导入操作系统
    #导入方法
    root=os.getcwd()
    对于['subdir1','subdir2']中的d:
    chdir(os.path.join(root,d))
    打印(“dir:,os.getcwd())
    exec(打开(“../driver.py”).read())
    
    我也不确定您是否需要popen,因为python能够使用exec函数执行python文件。在这种情况下,这取决于如何导入methods.py。您是简单地导入它还是在driver.py中以其他方式使用它?
    您可以尝试在主脚本的顶层导入它,或使用扩展路径,如:

    exec(打开(“../methods.py”).read())
    
    在驱动程序脚本的内部。请记住,这些解决方案都不是很优雅。最好是按照Gino Mempin的建议处理driver.py中的路径。您可以从那里调用os.chdir()。

    展开,而不是到处复制driver.py,您只需让它接受子目录的路径作为命令行参数即可。然后,您还必须确保它可以从任何目录执行它应该执行的任何操作。这意味着要考虑到文件的正确路径

    有许多方法可以接受命令行参数(请参阅)。为了简单起见,让我们使用
    sys.args
    来获取路径

    这是一个经过修改的驱动程序.py

    导入系统 从pathlib导入路径 #作为命令行参数接收目标子目录的路径 尝试: subdir_path=path(sys.argv[1]).resolve() 例外情况除外,如e: 打印('解析子目录路径时出错') 打印(e) 系统出口(1) #做一些事情,考虑到子目录的完整路径 打印(f'Running driver on{subdir_path}') 将open(subdir_path.joinpath('input.txt'),'r')作为f: data=f.read() 打印(f'Got data={data}') 假设获取路径后,driver.py希望从每个子目录中读取一个文件(input.txt)。因此,这里需要获得子目录()的绝对路径,并在访问input.txt()时使用该路径。基本上,认为driver.py总是从main目录运行

    示例用法为:

    main$tree
    .
    ├── driver.py
    ├── 方法.py
    ├── 次曲面1
    │   └── 输入文件
    ├── 次曲面2
    │   └── 输入文件
    └── 细分3
    └── 输入文件
    main$python driver.py/temp/main/subdir3
    在/temp/main/subdir3上运行驱动程序
    获得数据=3333
    
    现在,在method.py中,您不需要“copy driver.py”代码。只需循环遍历main下的所有子目录{n}文件夹,然后将完整路径传递到driver.py。您仍然可以使用相同的
    Popen(…)
    code调用driver.py

    下面是一个经过修改的方法。py

    导入子流程
    从pathlib导入路径
    #假设所有子目录都在当前目录下
    父路径=路径.cwd()
    对于父路径中的子路径。iterdir():
    #跳过未命名为“subdir{n}”的文件/文件夹
    如果不是child_path.is_dir()或'subdir'不在child_path.stem中:
    持续
    #iterdir返回完整路径(cwd+/subdir)
    打印(f'Calling driver.py on{child_path}')
    cmd=f'python driver.py{child_path}'
    p=subprocess.Popen(cmd,shell=True)
    p、 等等
    
    样本运行:

    main$python method.py
    在/temp/main/subdir3上调用driver.py
    在/temp/main/subdir3上运行驱动程序
    获得数据=3333
    正在调用driver.py on/temp/main/subdir2
    在/temp/main/subdir2上运行驱动程序
    获得数据=2222
    正在调用driver.py on/temp/main/subdir1
    在/temp/main/subdir1上运行驱动程序
    获取数据=1111
    
    还要注意,所有执行都是从main完成的

    一些注意事项:

    • 与硬编码的
      range(n)
      不同,您可以使用或其等效项获取基本路径下的所有文件/文件夹,基本路径应方便地返回绝对路径。除非你需要按特定的顺序通过这些细分
    • 我更喜欢使用over,因为它为文件/文件夹路径提供了更多高级抽象。如果您想要或需要使用
      os.path
      ,这里有一个
    • 我在这里使用了f-strings(请参阅),它仅适用于Python3.6+。如果您使用的是较低版本,只需替换为任何其他字符串格式设置方法

    为什么不修改driver.py以接受目录路径?这样,您就可以在子目录上循环并执行
    python driver.py/path/to/subdir{i}
    。您可能还需要确保driver.py代码可以从任何输入目录工作。@GinoMempin,哦,让它接受整个目录作为输入吗?我实际上没有做过这样的事情,但我可以找到一些东西来学习如何去做。非常感谢。感谢您的回答@areop enap!我只导入methods.py。os,chdir(os.path.join