Python调用外部程序的9种方式,你都知道吗?

前言

    外部程序,测试人员最长使用adb程序,在Python程序中调用adb程序,称为调用外部程序,你可能用过os.system()、os.popen()等等方式,官方推荐的是subprocess模块中的run()函数,今天就把python中所有可用于调用外部程序的方式都写他它一遍,各位方便用哪个都可以!

第一种方式:os.system()

    os模块下的system函数,可用于执行外部程序,传入参数为具体的命令,比如

import os

os.system("adb devices")

print("haha,我会等上面的程序执行完毕")

输出

List of devices attached

haha,我会等上面的程序执行完毕

特点1:List of devices attached 是 adb devices的标准输出,也就是说外部程序在子进程中的标准输出,也会和python当前主进程的标准输出中一起输出,从进程角度看,子进程使用父进程的标准输出,太正常不过了!

特点2:子进程中执行外部命令时,会阻塞当前python脚本进程的进度,所以你看到了:haha,我会等上面的程序执行完毕的输出

特点3:os.system()根据平台的不同(类Linux或者Windows),返回值表示退出状态码

特点4:无法在程序中获取到外部程序的标准输出,不方便我们在程序处理

特点5:完全绕开了bash,与bash无关,这里是直接执行了程序adb

特点6:标准错误也会和父进程中的输出在一起

第二种方式:os.popen

os模块下的popen函数,3个参数,第一个参数表示命令、第二个参数表示模式(r表示读管道、w表示写管道),第三个参数表示管道缓冲区大小,返回是个类似file的对象,具体是os模块下的_wrap_close类的对象,返回值是代表连接到管道的文件对象

import os

file_like = os.popen("adb devices")

print(file_like.read())

print("haha,我会等上面的程序执行完毕")

特点1:内部使用subprocess.Popen 实现

特点2:由于返回的是一个代表管道的文件对象,read()方法可以获取外部程序的所有标准输出,返回的是一个字符串

特点3:常用的readlines(),以换行符作为分隔,返回一个包含所有标准输出的list,每行一个元素

特点4:waitstatus_to_exitcode() 可以将 close()方法的返回值转为退出状态码

特点5:同样会阻塞当前主进程的执行流,直到子进程中程序执行完毕

第三种方式:subprocess.getoutput()

import subprocess

output = subprocess.getoutput("adb devices")

print(output)

print("等待外部程序执行结束")

特点1:内部使用subprocess.getstatusoutput()实现

特点2:可以方便的获取标准输出

特点3:同样会阻塞python主进程的执行,直到拿到外部程序的标准输出

第四种方式:subprocess.getstatusoutput()

import subprocess

output = subprocess.getstatusoutput("adb devices")

print(output)

print("等待外部程序执行结束")

特点1:内部使用subprocess.check_output()

特点2:返回值是个元组,类似这样。(0, 'List of devices attached\n'),第一个元素代表退出状态码、第二个元素代表标准输出

第五种方式:subprocess.check_output()

import subprocess

output = subprocess.check_output("adb devices")

print(output)

print("等待外部程序执行结束")

特点1:内部使用subprocess.run()

特点2:返回的是字节串对象,而不是字符串对象,需要自行转换

特点3:可以控制标准错误、外部程序执行时间、录入标准输入、是否使用bash等等选项(注意:默认情况下并没有经过bash解释器)

特点4:退出状态码非0,抛出的异常是CalledProcessError

特点5:待续

第六种方式:subprocess.run()

import subprocess

output = subprocess.run("adb devices")

print(output)

print("等待外部程序执行结束")

输出

List of devices attached

CompletedProcess(args='adb devices', returncode=0)
等待外部程序执行结束

特点1:内部使用subprocess.Popen类,每个Popen对象代表子进程

特点2:默认外部程序的标准输出,使用python进程器主进程的标准输出

特点3:默认返回为CompletedProcess对象

特点4:这个可以更灵活的控制子进程中执行的程序,标准输入、标准输出、标准错误、退出状态码等等随便拿着用

第七种方式:subprocess.Popen

import subprocess

output = subprocess.Popen("adb devices")

print(output)

print("等待外部程序执行结束")

特点1:可以最大程序的控制子进程中执行程序

特点2:替代os模块在子进程中执行程序

特点3:返回的是Popen对象

 第八种方式:subprocess.call()

import subprocess

output = subprocess.call("adb devices")

print(output)

print("等待外部程序执行结束")

特点1:返回值为退出状态码

特点2:同样会等待子进程执行程序结束

第九种方式:subprocess.check_call()

import subprocess

output = subprocess.check_call("adb devices")

print(output)

print("等待外部程序执行结束")

特点1:依赖subprocess.call()

特点2:返回值退出状态码,非0时返回CalledProcessError对象

总结

1、官方提供这么多种执行外部程序的方式,我相信与标准的制定有关,每个方式都不完美,但总有适合你的

2、它们都会阻塞当前进程

3、官方建议使用subprocess下的方式,而不建议使用os下的方式

4、subprocess模块的源码非常值得一读

5、肯定还有其他调用外部程序的方式,不过这些真的够用了

你可能感兴趣的:(Python,综合,python,开发语言,adb)