【问题标题】:How to execute a python script in a different directory?如何在不同的目录中执行 python 脚本?
【发布时间】:2018-01-05 04:03:16
【问题描述】:

已解决请在下方查看我的回答,供任何可能觉得这很有帮助的人参考。

我有两个脚本 a.py 和 b.py。 在我当前的目录“C:\Users\MyName\Desktop\MAIN”中,我运行 > python a.py.

第一个脚本 a.py 在我的当前目录中运行,对一堆文件执行一些操作并创建一个新目录 (testA),其中包含这些文件的编辑版本,这些文件同时移动到该新目录中。然后我需要为 testA 中的文件运行 b.py。

作为初学者,我只需将我的 b.py 脚本复制并粘贴到 testA 中,然后再次执行命令 "> python b.py",它会在这些新文件上运行一些命令并使用这些文件创建另一个文件夹 (testB)编辑过的文件。

我试图消除等待 a.py 完成的麻烦,进入新目录,粘贴 b.py,然后运行 ​​b.py。我正在尝试编写一个 bash 脚本来执行这些脚本,同时保持我的目录层次结构。

#!/usr/bin/env bash
 python a.py && python b.py

脚本 a.py 运行顺利,但 b.py 根本不执行。没有出现关于 b.py 失败的错误消息,我只是认为它无法执行,因为一旦 a.py 完成,b.py 在那个 NEW 目录中就不存在了。 我可以在 b.py 中添加一个小脚本,将其移动到新目录中吗?我实际上也尝试过更改 b.py 目录路径,但没有成功。

例如在 b.py 中:

mydir = os.getcwd() # would be the same path as a.py
mydir_new = os.chdir(mydir+"\\testA")

我在 b.py 中的所有实例中都将 mydirs 更改为 mydir_new,但这也没什么区别...我也不知道如何将脚本移动到 bash 中的新目录中。

作为文件夹的小流程图:

MAIN # main folder with unedited files and both a.py and b.py scripts
|
| (execute a.py)
|
--------testA # first folder created with first edits of files
         |
         | (execute b.py)
         |
         --------------testB # final folder created with final edits of files

TLDR:如果 b.py 依赖于在 testA 中创建和存储的文件,我如何从主测试文件夹(bash 脚本样式?)执行 a.py 和 b.py。通常我将 b.py 复制并粘贴到 testA 中,然后运行 ​​b.py - 但现在我有 200 多个文件,所以复制和粘贴是浪费时间。

【问题讨论】:

  • 使用..module_name访问当前目录上方目录中的模块
  • 我现在可以在我的主目录中使用 b.py。 bash 脚本不会执行 b.py 但是一旦 a.py 完成。如果我输入“python a.py”,那么“python b.py”它就可以了。不知道为什么“python a.py & python b.py”不做同样的事情。
  • 没关系,我终于明白了,这只是一个愚蠢的错字!拥有“python a.py & python b.py”在 bash 脚本中确实有效!

标签: python bash python-2.7


【解决方案1】:

最简单的答案可能是更改您的工作目录,然后从它所在的位置调用第二个.py 文件:

python a.py && cd testA && python ../b.py

当然,您可能会发现编写一个为您完成所有工作的脚本会更容易,如下所示:

将此作为runTests.sh保存在与a.py相同的目录中:

#!/bin/sh
python a.py
cd testA
python ../b.py

使其可执行:

chmod +x ./runTests.sh

然后你可以简单地进入你的目录并运行它:

./runTests.sh

【讨论】:

  • 对不起,我不是很擅长 linux,但我正在学习。我首先在我的 cmd 窗口中运行 chmod 命令,然后执行 runTests.sh? chmod 行让我感到困惑,因为我以前从未使用过它。我也想试试你的方法(除了我自己的方法,这可能不是最好的,因为它确实涉及稍微更改 b.py 脚本)
  • 哦,成功了! chmod 是每次都需要输入的东西吗?或者它也可以是 bash 脚本的一部分?
  • chmod 行运行一次。这告诉系统它是一个可执行文件,并且允许执行它。它应该只需要在您想要使其可执行的每个文件上运行一次,除非您在文件上运行了相反的chmod -x 命令,这将告诉系统不允许执行它。
【解决方案2】:

我设法让 b.py 在我需要的地方执行和生成 testB 文件夹,同时保留在 MAIN 文件夹中。对于任何可能想知道的人,在我的 b.py 脚本的开头,我会简单地使用 mydir = os.getcwd() 这通常是 b.py 所在的位置。

为了将 b.py 保留在 MAIN 中,同时使其适用于其他目录中的文件,我这样写:

mydir = os.getcwd() # would be the MAIN folder
mydir_tmp = mydir + "//testA" # add the testA folder name
mydir_new = os.chdir(mydir_tmp) # change the current working directory
mydir = os.getcwd() # set the main directory again, now it calls testA

现在可以运行 bash 脚本了!

【讨论】:

  • 为什么要使用两个正斜杠? windows 上的反斜杠需要另一个来转义,但是双正斜杠没有意义。
【解决方案3】:

您的b.py 脚本可以将目录名称作为参数。访问传递给b.py 的第一个参数:

import sys
dirname = sys.argv[1]

然后遍历命名目录中的文件:

import os
for filename in os.listdir(dirname):
    process(filename)

另请参阅glob.globos.walk 了解更多选项处理文件。

【讨论】:

    【解决方案4】:

    尽管已经有了答案,但我仍然出于乐趣而编写了一个脚本,并且在某些方面仍然可以提供帮助。 我是为 python3 编写的,所以需要调整一些小东西才能在 v2.x 上执行它(例如打印)。

    无论如何...代码创建一个相对于 a.py 位置的新文件夹,创建并用代码填充脚本 b.py,执行 b 并显示 b 的结果和错误。

    生成的路径结构是: 测试文件夹 |-测试A | |-a.p​​y |-测试B | |-b.py

    代码是:

    import os, sys, subprocess
    
    def getRelativePathOfNewFolder(folderName):
        return "../" + folderName + "/"
    
    def getAbsolutePathOfNewFolder(folderName):
        # create new folder with absolute path:
        #   get path of current script:
        tmpVar = sys.argv[0]
        #   separate path from last slash and file name:
        tmpVar = tmpVar[:sys.argv[0].rfind("/")]
        #   again to go one folder up in the path, but this time let the slash be:
        tmpVar = tmpVar[:tmpVar.rfind("/")+1]
        #   append name of the folder to be created:
        tmpVar += folderName + "/"
    
        # for the crazy ones out there, you could also write this like this:
        # tmpVar = sys.argv[0][:sys.argv[0].rfind("/", 0, 
        sys.argv[0].rfind("/")-1)+1] + folderName + "/"
        return tmpVar
    
    if __name__ == "__main__":
        # do stuff here:
        # ...
        # create new folder:
        bDir = getAbsolutePathOfNewFolder("testB")
        os.makedirs(bDir, exist_ok=True) # makedirs can create new nested dirs at once. e.g: "./new1/new2/andSoOn"
        # fill new folder with stuff here:
        # ...
        # create new python file in location bDir with code in it:
        bFilePath = bDir + "b.py"
        with open(bFilePath, "a") as toFill:
            toFill.write("if __name__ == '__main__':")
            toFill.write("\n")
            toFill.write("\tprint('b.py was executed correctly!')")
            toFill.write("\n")
            toFill.write("\t#do other stuff")
    
        # execute newly created python file
        args = (
            "python",
            bFilePath
        )
        popen = subprocess.Popen(args, stdout=subprocess.PIPE)
        # use next line if the a.py has to wait until the subprocess execution is finished (in this case b.py)
        popen.wait()
        # you can get b.py´s results with this:
        resultOfSubProcess, errorsOfSubProcess = popen.communicate()
        print(str(resultOfSubProcess)) # outputs: b'b.py was executed correctly!\r\n'
        print(str(errorsOfSubProcess)) # outputs: None
    
        # do other stuff
    

    您当然可以简单地复制现有的,而不是创建一个新的代码文件并用代码填充它,如下所示: How do I copy a file in python?

    【讨论】:

      【解决方案5】:

      在您的批处理文件中,您可以将 %PYTHONPATH% 变量设置为包含 Python 模块的文件夹。这样,您不必更改目录或将 pushd 用于网络驱动器。我相信你也可以做类似的事情

      set "PYTHONPATH=%PYTHONPATH%;c:\the path\to\my folder\which contains my module"
      

      这将附加我认为的路径(这仅在您已经在环境变量中设置 %PYTHONPATH% 时才有效)。

      如果你没有,你也可以这样做

      set "PYTHONPATH=c:\the path\to\my folder\which contains my module"
      

      然后,在同一个批处理文件中,您可以执行类似的操作

      python -m mymodule ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-04
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 2021-05-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多