2015-05-14 23 views
0

有这个python脚本(找到here),我用它来显示我的笔记本电脑的电池百分比作为我的$PROMPT的一部分。它适用于python(又名版本2)。但它不适用于python3。这是一个问题,因为我使用pyenv和pyenv-virtualenv来处理项目,有时python命令指向3+版本。当电池的脚本进行评估产生的终端这些错误:TypeError:类型str不支持缓冲区API

Traceback (most recent call last):            
    File "/usr/local/bin/batcharge.py", line 9, in <module> 
    o_max = [l for l in output.splitlines() if 'MaxCapacity' in l][0] 
    File "/usr/local/bin/batcharge.py", line 9, in <listcomp> 
    o_max = [l for l in output.splitlines() if 'MaxCapacity' in l][0] 
TypeError: Type str doesn't support the buffer API 

这里是文件,这是很短的,如果有人能帮忙鉴定一下是怎么回事。

#!/usr/bin/env python 
# coding=UTF-8 

import math, subprocess 

p = subprocess.Popen(["ioreg", "-rc", "AppleSmartBattery"], stdout=subprocess.PIPE) 
output = p.communicate()[0] 

o_max = [l for l in output.splitlines() if 'MaxCapacity' in l][0] 
o_cur = [l for l in output.splitlines() if 'CurrentCapacity' in l][0] 

b_max = float(o_max.rpartition('=')[-1].strip()) 
b_cur = float(o_cur.rpartition('=')[-1].strip()) 

charge = b_cur/b_max 
charge_threshold = int(math.ceil(10 * charge)) 

# Output 

total_slots, slots = 10, [] 
filled = int(math.ceil(charge_threshold * (total_slots/10.0))) * u'▸' 
empty = (total_slots - len(filled)) * u'▹' 

out = (filled + empty).encode('utf-8') 
import sys 

color_green = '%{[32m%}' 
color_yellow = '%{[1;33m%}' 
color_red = '%{[31m%}' 
color_reset = '%{[00m%}' 
color_out = (
    color_green if len(filled) > 6 
    else color_yellow if len(filled) > 3 
    else color_red 
) 

out = color_out + out + color_reset 
sys.stdout.write(out) 

显然,python3窒息列表中的理解的东西,但我想不出什么。

根据外壳,这就是由output.splitlines()程序崩溃之前返回:

[b'+-o AppleSmartBattery <class AppleSmartBattery, id 0x1000001dc, registered, matched, active, busy 0 (1 ms), retain 6>', b' {', b'  "ExternalConnected" = Yes', b'  "TimeRemaining" = 0', b'  "InstantTimeToEmpty" = 65535', b'  "ExternalChargeCapable" = Yes', b'  "FullPathUpdated" = 1431620425', b'  "CellVoltage" = (4148,4147,4147,0)', b'  "Voltage" = 12442', b'  "BatteryInvalidWakeSeconds" = 30', b'  "AdapterInfo" = 0', b'  "MaxCapacity" = 5886', b'  "PermanentFailureStatus" = 0', b'  "Manufacturer" = "SMP"', b'  "Location" = 0', b'  "CurrentCapacity" = 5727', b'  "LegacyBatteryInfo" = {"Amperage"=0,"Flags"=5,"Capacity"=5886,"Current"=5727,"Voltage"=12442,"Cycle Count"=539}', b'  "FirmwareSerialNumber" = 27251', b'  "BatteryInstalled" = Yes', b'  "PackReserve" = 200', b'  "CycleCount" = 539', b'  "DesignCapacity" = 6900', b'  "OperationStatus" = 58435', b'  "ManufactureDate" = 15675', b'  "AvgTimeToFull" = 65535', b'  "BatterySerialNumber" = "W0040P2ABBWZA"', b'  "BootPathUpdated" = 1430956311', b'  "PostDischargeWaitSeconds" = 120', b'  "Temperature" = 3036', b'  "UserVisiblePathUpdated" = 1431620485', b'  "InstantAmperage" = 0', b'  "ManufacturerData" = <000000000201000a01580000034b3138033030410341544c00130000>', b'  "MaxErr" = 1', b'  "FullyCharged" = Yes', b'  "DeviceName" = "bq20z451"', b'  "IOGeneralInterest" = "IOCommand is not serializable"', b'  "Amperage" = 0', b'  "IsCharging" = No', b'  "DesignCycleCount9C" = 1000', b'  "PostChargeWaitSeconds" = 120', b'  "AvgTimeToEmpty" = 65535', b' }', b' ', b''] 

triedotherpages这里有相同的错误,并且是建议的修复程序不为我工作。

也就是说,bytes(l, 'utf-8')l.encode('utf-8')不起作用。请指教。

回答

0

很简单,在b的列表理解的可选谓词前加上字符串,将它们编码为bytes而不是字符串。因此,行9和10变成:

o_max = [l for l in output.splitlines() if b'MaxCapacity' in l][0] 
o_cur = [l for l in output.splitlines() if b'CurrentCapacity' in l][0] 

虽然我正确的认识有一个与列表理解的问题,我没能找出什么;这个答案显然隐藏在可见的范围内。我一直试图转换l中存储的内容,而不是关注代码中的字符串。留在这里希望帮助别人。

+1

另一种方法是向'universal_newlines = TRUE'参数添加到'subprocess.Popen()'呼叫。 –

相关问题