【发布时间】:2019-01-13 00:13:26
【问题描述】:
我有一个脚本在 .pyw 中可以正常工作,但是当转换为 .exe 时,(编辑:实际上,当我使用带有参数 -w 或 --windowed 或 --noconsole 的 pyinstaller 时,它不会t 工作,但没有它们它工作)我发现这一行似乎使程序崩溃:
firstplan = subprocess.check_output(["powercfg", "-list"], shell=True ).split('\n')[3]
有人知道为什么吗?如果我将其注释掉,程序不会崩溃。我还有另外两条非常相似的线。
编辑:
也许把脚本放在这里是个好主意……
from __future__ import print_function
import os
# os.system('cls')
import psutil
import subprocess
loop = 1
while loop == (1):
CPUload = (psutil.cpu_percent(interval=4)) # CPU load
RAMload = (psutil.virtual_memory().percent) # RAM load
# os.system('cls')
print("CPU Load: ", end="") # Display CPU Load:
print(CPUload, "%") # Display CPUload
print("RAM Load: ", end="") # Display CPU Load:
print(str(RAMload) + " %") # Display RAMload
firstplan = subprocess.check_output(["powercfg", "-list"], shell=True ).split('\n')[3] # Selects a line
secondplan = subprocess.check_output(["powercfg", "-list"], shell=True ).split('\n')[4]
thirdplan = subprocess.check_output(["powercfg", "-list"], shell=True ).split('\n')[5]
firstplanID = ((firstplan.split(": "))[1].split(" (")[0]) # Extract XplanID from Xplan
secondplanID = ((secondplan.split(": "))[1].split(" (")[0])
thirdplanID = ((thirdplan.split(": "))[1].split(" (")[0])
activeplan = subprocess.check_output(["powercfg", "/getactivescheme"]) # Find the currently active plan
activeplanNAME = ((activeplan.split("("))[1].split(")")[0]) # Extract activeplanNAME from activeplan
firstplanNAME = ((firstplan.split("("))[1].split(")")[0]) # Extract XplanNAME from Xplan
secondplanNAME = ((secondplan.split("("))[1].split(")")[0])
thirdplanNAME = ((thirdplan.split("("))[1].split(")")[0])
if "High performance" in firstplanNAME: # Identify which plan is High performance
HighPerformance = firstplanNAME
HighPerformanceID = firstplanID
if "High performance" in secondplanNAME:
HighPerformance = secondplanNAME
HighPerformanceID = secondplanID
if "High performance" in thirdplanNAME:
HighPerformance = thirdplanNAME
HighPerformanceID = thirdplanID
if "Power saver" in firstplanNAME: # Identify which plan is Power saver
PowerSaver = firstplanNAME
PowerSaverID = firstplanID
if "Power saver" in secondplanNAME:
PowerSaver = secondplanNAME
PowerSaverID = secondplanID
if "Power saver" in thirdplanNAME:
PowerSaver = thirdplanNAME
PowerSaverID = thirdplanID
if activeplanNAME == PowerSaver: # Checks current plan name
print("Active plan: Power saver")
else:
if activeplanNAME == HighPerformance:
print("Active plan: High Performance")
else:
subprocess.check_output(["powercfg", "/s", HighPerformanceID])
if CPUload < 44:
if RAMload > 90:
if activeplanNAME == PowerSaver:
subprocess.check_output(["powercfg", "/s", HighPerformanceID])
print("Switching to High Performance by RAM load...")
if CPUload < 44:
if RAMload < 90:
if activeplanNAME == HighPerformance:
subprocess.check_output(["powercfg", "/s", PowerSaverID])
print("Switching to Power saver...")
if CPUload > 55:
if activeplanNAME == PowerSaver:
subprocess.check_output(["powercfg", "/s", HighPerformanceID])
print("Switching to High Performance...")
有问题的行是第 21-23 行。
如需更多信息,请向下滚动至 cmets 和答案。
【问题讨论】:
-
使用
shell=True将命令作为列表传递显然恰好在某些平台上工作,但实际上不是正确的事情。取出shell=True。 (不过,我认为这不会解决您的问题。) -
您共享的脚本中的缩进显然是错误的(靠近开头的
while循环之后的部分或全部行应该缩进)。请注意发布有效代码;缩进对 Python 尤其重要。另请参阅Markdown help。 -
subprocess文档有详细信息。如果你使用shell=True,你应该传入一个字符串供shell解析;使用shell=False(或没有shell=True),您需要传入已解析令牌的列表。 -
显式比隐式好,所以改成
shell=False虽然技术上把它去掉也会做同样的事情。 -
调用一个 shell 三次来从同一个命令得到三行输出也是相当浪费的。只需执行
pcfg = subprocess.check_output(['powercfg', '-list']).split('\n')然后first = pcfg[3]、second = pcfg[4]等。
标签: python split subprocess pyinstaller strsplit