TypeError:类型str不支持缓冲区API

时间:2015-05-14 19:20:50

标签: string python-3.x buffer

我用这个python脚本(找到here)来显示笔记本电脑的电池百分比,作为$PROMPT的一部分。它适用于python(又称版本2)的魅力。但它不能与python3一起使用。这是一个问题,因为我使用pyenv和pyenv-virtualenv来处理项目,有时python命令指向3+版本。在评估电池脚本时,这会在终端中产生这些错误:

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会阻碍列表理解中的某些内容,但我无法弄清楚是什么。

根据shell,这是程序崩溃之前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'']

我在tried other pages这里有相同的错误,建议的修补程序对我不起作用。

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

1 个答案:

答案 0 :(得分: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中存储的内容,而不是关注代码中的字符串。离开这里希望能帮助别人。