在后台执行外部 Python 文件并在 python 中获取输出
Executing external Python file in background and get output in python
我有一个 python 文件,它接受一些输入并根据这些输入打印输出。我试图在另一个脚本中执行这个脚本。我需要做的就是向这个文件发送一些参数并在这个脚本中获取输出。
我需要执行的脚本:
while True:
print("Sabah 1")
print("Oglen 2")
print("Aksam 3")
print("Gece 4")
print("---------")
secim = raw_input("Gun icerisindeki zaman dilimini giriniz")
isim = raw_input("Isminizi giriniz.")
if (secim=='1') :
print("Gunaydin"+isim)
elif (secim == '2'):
print("Tunaydin"+isim)
elif (secim == '3'):
print("iyi aksamlar"+isim)
elif (secim == '4'):
print("Iyi geceler"+isim)
else:
print("Program sonlandiriliyor")
break
应该执行上面脚本的脚本:
import subprocess, threading, time
can_break = False
def run():
args = ['python','odev2.py','arg1','arg2']
popen = subprocess.Popen(args,shell=False,stdout=subprocess.PIPE)
while not can_break:
print(popen.stdout.readline())
t = threading.Thread(target=run)
try:
t.start()
while True:
print('Main Thread.... ')
time.sleep(1)
except KeyboardInterrupt:
can_break_break = True
问题是第二个脚本的输出一直在打印'Main Thread...'我无法读取任何输出。
谢谢。
我想您想知道为什么您没有看到来自 odev2.py 的任何提示?
简短的回答是将 运行 替换为:
def run():
args = ['python','-u','odev2.py','arg1','arg2']
popen = subprocess.Popen(args,shell=False,stdout=subprocess.PIPE)
while not can_break:
sys.stdout.write(popen.stdout.read(1))
长答案是有两个问题。
首先,有缓冲。 IO 很昂贵,因此 File 对象有时不会将数据收集在缓冲区中,而是在缓冲区已满时才写出数据,而不是立即写出数据。内置文件对象(如 sys.stdout)将根据写入内容决定缓冲。如果他们正在写入终端,那么他们将关闭缓冲,以便输出立即到达用户。但是如果他们正在写入文件,他们会缓冲以提高效率。
因此,当您在命令行 运行 odev2.py 时,打印正在写入终端,因此它是无缓冲的,您的提示会立即出现。但是当你 运行 odev2.py 与 subprocess(stdout=PIPE) 时,odev2.py 正在获取一个管道作为标准输出,以便文件对象缓冲。这意味着您没有看到提示。
您可以在命令行中使用 'python odev2.py arg1 arg2 | cat' 查看相同的效果 运行ning odev2.py。这会将标准输出设置为管道,您不会看到任何提示,但 odev2.py 将等待您输入。
这个缓冲问题可以通过让 odev2.py 自己编写提示(而不是让 raw_input 打印它们)然后在适当的时候调用 sys.stdout.flush() 来解决.但是一种快速而肮脏的方法是 运行 python 带有关闭所有缓冲的 -u 标志。试试 'python -u odev2.py arg1 arg2 | cat' 看看区别。
Note: -u turns off all buffering, which can have a huge impact on performance. So this is only a quick and dirty solution
其次,您的阅读线程使用readline。 readline 在看到换行符之前不会 return,但是 odev2.py 的提示不会以换行符结尾。所以 运行 中的 readline 不会 return 直到 odev2.py 发送一个换行符,但是 odev2 不会发送一个换行符直到它从你那里读取一些输入。所以你陷入了僵局。
解决这个问题的可靠解决方案是用 non-blocking IO 替换 readline,这样 return 你可以得到什么。但是 there doesn't seem 是在 python 2.7 中做到这一点的一种便携方式。所以快速黑客是做单字符读取。所以不用做 popen.stdout.readline(),你只要做 popen.stdout.read(1).
我有一个 python 文件,它接受一些输入并根据这些输入打印输出。我试图在另一个脚本中执行这个脚本。我需要做的就是向这个文件发送一些参数并在这个脚本中获取输出。
我需要执行的脚本:
while True:
print("Sabah 1")
print("Oglen 2")
print("Aksam 3")
print("Gece 4")
print("---------")
secim = raw_input("Gun icerisindeki zaman dilimini giriniz")
isim = raw_input("Isminizi giriniz.")
if (secim=='1') :
print("Gunaydin"+isim)
elif (secim == '2'):
print("Tunaydin"+isim)
elif (secim == '3'):
print("iyi aksamlar"+isim)
elif (secim == '4'):
print("Iyi geceler"+isim)
else:
print("Program sonlandiriliyor")
break
应该执行上面脚本的脚本:
import subprocess, threading, time
can_break = False
def run():
args = ['python','odev2.py','arg1','arg2']
popen = subprocess.Popen(args,shell=False,stdout=subprocess.PIPE)
while not can_break:
print(popen.stdout.readline())
t = threading.Thread(target=run)
try:
t.start()
while True:
print('Main Thread.... ')
time.sleep(1)
except KeyboardInterrupt:
can_break_break = True
问题是第二个脚本的输出一直在打印'Main Thread...'我无法读取任何输出。
谢谢。
我想您想知道为什么您没有看到来自 odev2.py 的任何提示?
简短的回答是将 运行 替换为:
def run():
args = ['python','-u','odev2.py','arg1','arg2']
popen = subprocess.Popen(args,shell=False,stdout=subprocess.PIPE)
while not can_break:
sys.stdout.write(popen.stdout.read(1))
长答案是有两个问题。
首先,有缓冲。 IO 很昂贵,因此 File 对象有时不会将数据收集在缓冲区中,而是在缓冲区已满时才写出数据,而不是立即写出数据。内置文件对象(如 sys.stdout)将根据写入内容决定缓冲。如果他们正在写入终端,那么他们将关闭缓冲,以便输出立即到达用户。但是如果他们正在写入文件,他们会缓冲以提高效率。
因此,当您在命令行 运行 odev2.py 时,打印正在写入终端,因此它是无缓冲的,您的提示会立即出现。但是当你 运行 odev2.py 与 subprocess(stdout=PIPE) 时,odev2.py 正在获取一个管道作为标准输出,以便文件对象缓冲。这意味着您没有看到提示。
您可以在命令行中使用 'python odev2.py arg1 arg2 | cat' 查看相同的效果 运行ning odev2.py。这会将标准输出设置为管道,您不会看到任何提示,但 odev2.py 将等待您输入。
这个缓冲问题可以通过让 odev2.py 自己编写提示(而不是让 raw_input 打印它们)然后在适当的时候调用 sys.stdout.flush() 来解决.但是一种快速而肮脏的方法是 运行 python 带有关闭所有缓冲的 -u 标志。试试 'python -u odev2.py arg1 arg2 | cat' 看看区别。
Note: -u turns off all buffering, which can have a huge impact on performance. So this is only a quick and dirty solution
其次,您的阅读线程使用readline。 readline 在看到换行符之前不会 return,但是 odev2.py 的提示不会以换行符结尾。所以 运行 中的 readline 不会 return 直到 odev2.py 发送一个换行符,但是 odev2 不会发送一个换行符直到它从你那里读取一些输入。所以你陷入了僵局。
解决这个问题的可靠解决方案是用 non-blocking IO 替换 readline,这样 return 你可以得到什么。但是 there doesn't seem 是在 python 2.7 中做到这一点的一种便携方式。所以快速黑客是做单字符读取。所以不用做 popen.stdout.readline(),你只要做 popen.stdout.read(1).