随心所欲的运行你的python脚本

当我们用代码实现自己使用的小脚本时,构建GUI或者web前端明显是没必要的,在cmd中使用命令行快速调用会更加合适。但使用cmd 运行python有个很头疼的问题,运行.py脚本必须切换到python脚本所在的目录或提供脚本的绝对路径,这样并不方便。我们今天讲一下如何解决这个问题。

先来看看 最终效果

在这里插入图片描述

runpy conut_code

你可以在任何地方运行你的python脚本。不管cmd当前在哪。也不用记忆绝对路径。

环境变量

安装完python后大家肯定接触过环境变量这个东西,当我们没有为python配置环境变量时,在命令行直接python会显示“python不是可执行文件”。只有配置完环境变量后才可以调用python。环境变量记录了你的可执行文件的路径。当我们在cmd里运行时,系统会根据你配置的环境变量去找,如果找到就运行。当配置了环境变量就可以不提供完整路径去调用程序。

为什么.py脚本需要完整路径?

.py文件其实并不是可执行文件。python.exe 才是,当我们调用python <脚本名称> 时其逻辑是运行python.exe 。脚本名称只是提供给python.exe的一个参数而已。python.exe 读取你传的路径然后解释其中的内容然后运行。
在这里插入图片描述
代码的后续部分我们会慢慢讲。现在只需要看我箭头标注的地方。这行代码会打印python.exe的所有参数.
在这里插入图片描述
runpy.py只是个参数。真正的可执行文件是前面的python。这就是我们为什么需要提供完整路径。而无法通过环境变量来找到.py。

解决思路

runpy.bat

其实解决思路很简单。就是在python.exe 的调用上封装个可执行文件。
在window中我们可以选择.bat或.exe。由于我主要写python。写c还需要重新配置太麻烦。我们这里使用简单的.bat文件。
这个.bat文件,暂且跟着我的命名叫runpy.bat。后续大家可以修改。这里为了跟上我的思路暂时和我命名一样。

@echo off
python %~dp0\runpy.py %*

这个代码的意思是运行于runpy.bat同一目录下的runpy.py文件。并且把
runpy.bat接受到的所有参数都传递给runpy.py。.bat文件是可执行文件。把你的runpy.bat所在的路径添加到环境变量,就可以在cmd中直接通过runpy 来运行。

runpy.py

runpy.py 负责解析参数来运行最终的.py文件。注意 因为 runpy.bat写的是同一路径下的runpy.py 所以要把他们放在一起。

在这里插入图片描述

print("我是python")

为了检验,你的.bat是否正常我们先写个简单的逻辑。打印一句话。

然后你可以在任何路径下运行runpy。来运行文件。这里的逻辑是我们调用runpy。环境变量帮我们找到runpy.bat。runpy.bat再调用runpy.py

在这里插入图片描述
很好如果你成功了。我们可以开始下一步,完善runpy.py
事实上我们是在模拟环境变量的事情。
在这里插入图片描述
还是这个路径添加一个script_paths.txt文件。像环境变量一样放脚本路径。

if __name__ == "__main__":
    from sys import argv
    the_current_path = os.path.dirname(argv[0])
    script_paths_file = os.path.join(the_current_path, "script_paths.txt")

需要注意的是我们想要获取script_paths.txt 并不能通过"./“这个相对路径。此时用”./"获取的是何处调用了这个文件的路径而不是runpy.py 的目录.

if __name__ == "__main__":
    from sys import argv
    the_current_path = os.path.dirname(argv[0])
    script_paths_file = os.path.join(the_current_path, "script_paths.txt")
    #完整路径
    print("当前路径"+os.path.abspath("./"))

打印当前路径
在这里插入图片描述
是我们何处调用了脚本。我们需要获取runpy的路径需要

    the_current_path = os.path.dirname(argv[0])

这行代码为什么可以获取路径?

看.bat文件。

```bash
@echo off
python %~dp0\runpy.py %*

这里和python一样。所有相对路径都是调用时的路径。所以即使runpu.bat
和runpy.py在同一个路径也无法相对路径调用。而%~dp0就是可以获取runpu.bat所在的绝对路径。
%~dp0\runpy.py是传给python的第一个参数。我们就可以通过argv[0]获取第一个参数。os.path.dirname用于获取一个路径的目录部分。比如我们D:/doc/runpy.py os.path.dirname就会返回D:/doc/ 这样我们就可以获取runpy.py的目录。然后获取script_paths.txt文件。

if __name__ == "__main__":
    from sys import argv
    the_current_path = os.path.dirname(argv[0])
    script_paths_file = os.path.join(the_current_path, "script_paths.txt")
    #完整路径
    #print("当前路径"+os.path.abspath("./"))
    if argv[1] == "-add":
        with open(script_paths_file, "a") as f:
            f.write(argv[2] + "\n")
        print("添加成功")
    elif argv[1] == "-del":
        with open(script_paths_file, "r") as f:
            script_paths = [line.strip() for line in f.readlines()]
            if argv[2] not in script_paths:
                print("脚本不存在")
                exit()
        with open(script_paths_file, "w") as f:
            for script_path in script_paths:
                if script_path != argv[2]:
                    f.write(script_path + "\n")
        print("删除成功")
    elif argv[1] == "-all":
        print("\n打印所有脚本路径")
        with open(script_paths_file, "r") as f:
            script_paths = [line.strip() for line in f.readlines()]
            for script_path in script_paths:
                print(script_path)

后部面的部分就要根据参数来执行命令了。这里我们传递给runpy的参数都会传给runpy.py,runpy.py的路径也是个参数。所以我们后面的判断要从argv[1]开始而不是argv[0]。

我们写了三个参数分支。用于添加环境变量。就是简单的读写文件。

测试一下。
在这里插入图片描述

    from sys import argv
    the_current_path = os.path.dirname(argv[0])
    script_paths_file = os.path.join(the_current_path, "script_paths.txt")
    #完整路径
    # print("当前路径"+os.path.abspath("./"))
    if argv[1] == "-add":
        with open(script_paths_file, "a") as f:
            f.write(argv[2] + "\n")
        print("添加成功")
    elif argv[1] == "-del":
        with open(script_paths_file, "r") as f:
            script_paths = [line.strip() for line in f.readlines()]
            if argv[2] not in script_paths:
                print("脚本不存在")
                exit()
        with open(script_paths_file, "w") as f:
            for script_path in script_paths:
                if script_path != argv[2]:
                    f.write(script_path + "\n")
        print("删除成功")
    elif argv[1] == "-all":
        print("\n打印所有脚本路径")
        with open(script_paths_file, "r") as f:
            script_paths = [line.strip() for line in f.readlines()]
            for script_path in script_paths:
                print(script_path)
    else:
        py_name = argv[1]
        if not py_name.endswith(".py"):
            py_name += ".py"
        if "/" in py_name:
            py_name = py_name.replace("/", "\\")
        path = locate_the_script(py_name)
        args=""
        for i in argv[2:]:
            args+=i+" "
        os.system(f"python {path} {args}")
        print("执行完毕")

最后一个分支判断就是开始真正的执行我们想要的脚本。

接下来就是找到传进来的脚本名称的绝对路径然后在拼接个python执行就行。同样的把需要的参数传给python。

def locate_the_script(script_name):
    with open(script_paths_file , "r") as f:
        script_paths = [line.strip() for line in f.readlines()]
    if not script_paths:
        print("您必须指定一个路径")
        print(r"比如您的python脚本写在D:\script下")
        print(r"调用runpy -add D:\script")
        exit()

    for script_path in script_paths:
        for script in find_script(script_path):
            if script.endswith(script_name):
                return script
    exit("没有找到脚本")

这里只是提供了一个解决这个问题的思路。没仔细写。找路径的算法直接是循环。大家可以凭自己的技术实现快速找到路径的功能。比如用redis内存数据库,或者哈希表。

用法

我们可以在任何路径下编写python脚本。将目录用上文的 -add添加到我们的文件里。然后你就可以在任何地方。运行你的脚本。还不用记忆绝对路径。如果你的脚本名字取的好。那调用脚本就想和计算机说话一样。
最后展示这个脚本的便利。
比如一个统计代码行数的脚本。 在你需要统计代码行数的文件夹下。
在这里插入图片描述
右键,我们可以在终端打开。
在这里插入图片描述
就可以统计当前目录下的代码行数。并且命令可以说十分简单,还不用记录.py的路径。随地调用你的脚本。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

又跑神了吗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值