百宝箱

以我们目前三脚猫的功夫想写个功能完善界面友好的应用程序还是有些难度的,如果能在代码中调用外界已经成熟的应用软件“巧借东风”无疑会“有如神助”地在代码能实现的功能上完成大飞跃!另外现在也主张写实现有限功能&短小精悍的程序,各程序之间互相调用,联手完成复杂任务。比如手机上美食推荐的app,查找推荐美食的地点一般会调用其它地图应用定位完成,而不是在美食app上自己实现地图定位。

subprocess模块是一个调用外部程序的功能模块,python自带的功能很强大,这里我们只介绍比较经常和浅层的使用。

Mac终端窗口(terminal)上用命令行打开计算器应输入:

open /Applications/Calculator.app

Windows命令窗口(command)上用命令行打开计算器输入:

start calc 或者 calc

用python代码启动计算器就是:

import subprocess

Mac:
subprocess.run(['open', '/Applications/Calculator.app'])
# 第一个参数是列表,把命令行的命令和参数分别用字符串的形式放进列表里
或者
subprocess.run('open /Applications/Calculator.app', shell=True)
# 第一个参数是字符串,需要设置参数shell=True

Windows:
subprocess.run(['start', 'calc'], shell=True)
或者
subprocess.run('start calc', shell=True)
或者
subprocess.run('calc', shell=True)
# windows上无论第一个参数用列表还是字符串,shell=True必须设置

查看.txt.py之类的文本文件,MAC上可以用编辑器texteditWindowns上可以用笔记本notepad上。在MACterminal终端窗口上敲入命令:

open /Applications/Textedit.app '/users/PythonABC/documents/poem.txt'

代码实现就是:

MAC:
subprocess.run(['open', '/Applications/Textedit.app', '/users/PythonABC/documents/poem.txt'])
或者
subprocess.run('open /Applications/Textedit.app /users/PythonABC/documents/poem.txt', shell=True)

Windowscommand命令窗口上敲入命令:

start notepad c:\Users\PythonABC\Documents\poem.txt

或者:

notepad c:\Users\PythonABC\Documents\poem.txt

subprocess.run(['start', 'notepad', 'c:\\Users\\PythonABC\\Documents\\poem.txt'], shell=True)	# 或者

subprocess.run('start notepad c:\\Users\\PythonABC\\Documents\\poem.txt', shell=True)	# 或者

subprocess.run(['notepad', 'c:\\Users\\PythonABC\\Documents\\poem.txt'], shell=True)	# 或者

subprocess.run('notepad c:\\Users\\PythonABC\\Documents\\poem.txt', shell=True)

推而广之就是找到外部应用程序的位置,替换掉'/Applications/Textedit.app';用要打开文件的路径+文件名字串替换掉'/users/PythonABC/documents/poem.txt'

也可以不指定打开文件的应用,系统会调用默认的应用:

Mac:
subprocess.run(['open', '/users/PythonABC/documents/poem.txt'])
subprocess.run('open /users/PythonABC/documents/datePlus.py', shell = True)

Windows:
subprocess.run('c:\\Users\\PythonABC\\Documents\\poem.txt', shell=True)
subprocess.run('c:\\Users\\PythonABC\\documents\\datePlus.py', shell=True)

Mac终端窗口运行python程序用:python3 /users/PythonABC/documents/datePlus.py

Mac上用’python3’是因为Mac自带了python2.7,如果用’python’调用的是python2.7的解释器。

Windows命令窗口运行python程序用:python c:\users\PythonABC\documents\datePlus.py

在python代码中实现则是:

Mac:
subprocess.run(['python3', '/users/PythonABC/documents/datePlus.py'])

Windows:
subprocess.run('python c:\\Users\\PythonABC\\documents\\datePlus.py', shell=True)

Mac终端窗口查询指定的目录(比如查询/users/PythonABC/documents目录)下的文件和子目录详细信息的命令是:

ls -l /users/PythonABC/documents

Windows命令窗口查询目录的命令是:dir c:\users\PythonABC\documents\

python代码中实现同样功能:

Mac:
subprocess.run('ls -l /users/PythonABC/documents', shell=True)

Windows:
subprocess.run('dir c:\\Users\\PythonABC\\documents', shell=True)

如果想把输出内容保存到文本文件或剪贴板中,Macterminal终端窗口上用命令:

ls -l /usrs/pythonABC/documents > folderContent.txt(文本文件)

ls -l /usrs/pythonABC/documents | pbcopy(剪贴板)

Windowscommand窗口用命令;

dir c:\Users\PythonABC\documents > folderContent.txt

dir c:\Users\PythonABC\documents | clip

python代码中实现用:

Mac:
subprocess.run('ls -l /users/PythonABC/documents > folderContent.txt', shell=True)	# 输出至文本文件
subprocess.run('ls -l /users/PythonABC/documents | pbcopy', shell=True)				# 输出至剪贴板

Windows:
subprocess.run('dir c:\\Users\\PythonABC\\documents > folderContent.txt, shell=True)	# 输出至文本文件
subprocess.run('dir c:\\Users\\PythonABC\\documents | clip', shell=True)				# 输出至剪贴板

pbcopyMAC命令行的copy操作,可以把文本内容送进剪贴板。打开terminal输入pbcopy < poem.txt,当前文件夹下的poem.txt的内容就进剪贴板了。pbpaste是粘贴命令,在terminal窗口上只敲pbpaste,剪贴板里的内容显示出来。敲pbpaste > pastetest.txt,则剪贴板的内容到文本文件pastetest.txt里。‘>’开口对着输入方,尖头对着输出方,当前目录下没有pastetest.txt会创建一个,已经有了则会被覆盖。

windows的命令clip可以把内容拷贝到剪贴板,但是把内容从剪贴板里拷贝出来的paste却不是系统自带的,而需要另外安装,所以这里不做介绍。

python代码来实现就是:

MAC:
subprocess.run('pbcopy < poem.text', shell=True)		# 文本文件->剪切板
subprocess.run('pbpaste > pastetest.txt', shell=True)	# 剪切板->文本文件

Windows:
subprocess.run('clip < poem.txt', shell=True)	# 文本文件->剪切板

在代码中把字符串内容送进剪贴板:

str = '苦乐年华'

commandStrMac = 'echo ' + str + ' | pbcopy'		# 适用MAC
或者
commandStrMac = 'echo ' + str + ' | clip'		# 适用Windows

subprocess.run(commandStr, shell=True)

‘苦乐年华’是中文,所以需要IOEncoding的编码是UTF-8,MACWindows上语言编码的设置:

Mac上command加空格调出搜索栏,搜索栏内输入terminal调出终端窗口。输入命令:locale,查看语言环境设置(决定字符集、货币值格式、时间日期格式……):


LC_CTYPE是管字符集的,把它的值改成’UTF-8’。打开terminal窗口->  点击Terminal菜单-> Preferences -> Profile -> Basic的Advanced下有个international -> Text encoding:选择Unicode(UTF-8),Set locale environment variables on start up没勾上的勾上,勾上的取消:

而后关闭terminal重新打开,输入locale:


还有个办法就是把用户根目录下的.bash_profile的编码全设成utf-8:

  • 到根目录去:Finder -> Go菜单-> Computer -> Macintosh HD -> Users -> 双击自己的账号名(比如PythonABC)
  • 找.bash_profile,文件名前面的‘.’说明这是个隐藏文件。若找不见这个文件,就按快捷三键command+shift+.让隐藏文件显现
  • 点开.bash_profile,在文件末尾加入:

export LC_ALL=en_US.UTF-8

export LANG=en_US.UTF-8

  • 保存关闭,重新打开terminal。输入locale,会发现所有的值被重置为UTF-8。这时候再把中文字符用subprocess送进粘贴板,ctrl+v出来的就是中文字符了。

如果是windows,先调出control panel(控制面板),选择clock, language and region(时间和语言),选择region(区域和语言)。点击administrative language setting,advanced如果是windows xp(管理语言设置)的管理标签。选择language for non-unicode program(Unicode程序的语言),点击

change system locale(更改系统区域设置),Current system locale设为中文,然后重启计算机。如果还是不能正常显示字符,把区域和语言下的显示语言(Windows display language)也设成中文。

subprocess.run()subprocess.Popen()的简化版。subprocess.Popen()把运行结果存放到PIPE管道里供后续使用:

Mac:
directory = '/users/PythonABC/documents'
proc1 = subprocess.Popen(['ls', '-l', directory], stdout=subprocess.PIPE)

Windows:
directory = 'c:\\Users\\PythonABC\\Documents'
proc1 =subprocess.Popen(['dir', directory], shell=True, stdout=subprocess.PIPE)

# 除了跟subprocess.run()一样的命令列表参数外,多了一个stdout=,指定输出结果放
# 进subprocess.PIPE

out1 = proc1.communicate()	# 把存放到subprocess.PIPE里的内容读出来

print(out1)	
# out1是个元组(tuple),元组的第一个元素out1[0]是输出内容
print(out1[0].decode())
# out1[0]是bytes类型,看着有点乱,解码decode()成字符串类型就看得懂了

subprocess.Popen()也可以把输出结果送到剪贴板上:

Mac:
proc1 = subprocess.Popen(['echo', '两两相忘'], stdout=subprocess.PIPE)
# 将“两两相忘”送进管道
subprocess.Popen(['pbcopy'], stdin=proc1.stdout) 
# 输入是管道里的内容,输出是剪贴板

Windows:
proc1 = subprocess.Popen(['echo', '两两相忘'], stdout=subprocess.PIPE, shell=True)
# 将“两两相忘”送进管道
subprocess.Popen(['clip'], stdin=proc1.stdout) 

最后这条语句跟subprocess模块无关,但在程序中打开网页也算是开第三方应用外挂,所以在这里提一下:

import webbrowser
webbrowser.open(‘PythonABC.org’)

即将推出的Python ABC教程对PythonABC视频内容进行了梳理,修正了发现的错误、对代码做了些许优化、替换掉视频中的英文注释、替换掉国内不能访问的资源、添加windows上运行的代码行……敬请关注,谢谢

欢迎访问PythonABC网站百宝箱,虽然现在只有仨宝,但我们会不断往里搬运宝贝哒~~~