一个跨平台的程序启动框架
示例:my_PP4E/launchmodes.py
"""
##############################################################################
用命令行和可复用的启动方案来启动Python程序;在命令行开头自动向Python可执行文件插入"python"
或路径;这个模块的某个部分可能假定Python在你的系统路径中。
使用subprocess模块也行,不过os.popen在内部调用这个模块,目标是在这里启动一个独立运行的程序
,而非连接到它的流;multiprocessing模块也是一个选择,不过这里处理命令行而非函数,为实现这里
的选项之一而开始一个进程不是很合理。
##############################################################################
"""
import sys
import os
PYFILE = (sys.platform[:3] == 'win' and 'python.exe') or 'python'
PYPATH = sys.executable
def fixWindowsPath(cmdline):
"""
将cmdline开头的脚本文件名路径中所有'/'改为'\\';在Windows下,仅为运行需要处理这种
工具的类所使用;在其他平台上,这么做也没有坏处
"""
splitline = cmdline.lstrip().split(' ')
fixedpath = os.path.normpath(splitline[0])
return ' '.join([fixedpath] + splitline[1:])
class LaunchMode:
"""
在实例中待命,声明标签并运行命令;子类按照run方法中的需要格式化命令行;命令应当以准
备运行的Python脚本名开头,而且不带“python”或脚本的完整路径。
"""
def __init__(self, label, command):
self.what = label
self.where = command
def __call__(self):
self.announce(self.what)
self.run(self.where)
def announce(self, text):
print(text)
def run(self, cmdline):
assert False, 'run must be defined'
class System(LaunchMode):
"""
运行shell命令行中指定的Python脚本;小心,可能会阻塞调用者,除非在Unix下带上&操
作符。
"""
def run(self, cmdline):
cmdline = fixWindowsPath(cmdline)
os.system('{} {}'.format(PYPATH, cmdline))
class Popen(LaunchMode):
"""
在新进程中运行shell命令行;小心,可能会阻塞其调用者,因为管道闭得太快
"""
def run(self, cmdline):
cmdline = fixWindowsPath(cmdline)
os.popen(PYPATH + ' ' + cmdline)
class Fork(LaunchMode):
"""
在显示地创建新进程中运行命令,仅在类Unix系统下可用,包括Cygwin
"""
def run(self, cmdline):
assert hasattr(os, 'fork'), 'platform not supported'
cmdline = cmdline.split()
if os.fork() == 0:
os.execvp(PYPATH, [PYFILE] + cmdline)
class Start(LaunchMode):
"""
独立于调用者运行程序;仅在Windows下可用:使用了文件名关联
"""
def run(self, cmdline):
assert sys.platform[:3] == 'win', 'platform not supported'
cmdline = fixWindowsPath(cmdline)
os.startfile(cmdline)
class StartArgs(LaunchMode):
"""
仅在Windows下可用:args可能需要用到真正的start命令;斜杠在这里没问题。
"""
def run(self, cmdline):
assert sys.platform[:3] == 'win', 'platform not supported'
os.system('start ' + cmdline)
class Spawn(LaunchMode):
"""
在独立于调用者的新进程中运行Python;在Windows和Unix下都可用;DOS中使用
P_NOWAIT;斜杠在这里没问题。
"""
def run(self, cmdline):
os.spawnv(os.P_DETACH, PYPATH, (PYPATH, cmdline))
class Top_level(LaunchMode):
"""
在新窗口中运行,进程是同一个;待讨论:还需要GUI类信息。
"""
def run(self, cmdline):
assert False, 'Sorry - mode not yet implemented'
if sys.platform[:3] == 'win':
PortableLauncher = Spawn
else:
PortableLauncher = Fork
class QuietPortableLauncher(PortableLauncher):
"""
不通知安静地用平台适用的方式启动程序
"""
def announce(self, text):
pass
def selftest():
file = 'echo.py'
input('default mode...')
PortableLauncher(file, file)()
input('system mode...')
System(file, file)()
if sys.platform[:3] == 'win':
input('DOS start mode...')
StartArgs(file, file)()
if __name__ == '__main__':
selftest()
示例:my_PP4E/echo.py
"测试"
print('Spam')
input('press Enter')
输出:my_PP4E/launchmodes.py
default mode...
echo.py
system mode...Spam
press Enter
echo.py
Spam
press Enter
———————————————————————————————————————————
😃 学完博客后,是不是有所启发呢?如果对此还有疑问,欢迎在评论区留言哦。 如果还想了解更多的信息,欢迎大佬们关注我哦,也可以查看我的个人博客网站BeacherHou。
|