【问题标题】:updating from python 2 to python 3从 python 2 更新到 python 3
【发布时间】:2020-04-15 16:07:09
【问题描述】:

我正在将用 python 2 编写的脚本更新为 python 3,这是我在尝试使用时正在学习的。这个 wxpython 控制的 LED 类导致错误:(TypeError: Expected a list of bytes objects.)我相信问题源于这个列表

xpm = ['17 17 5 1', # width height ncolors chars_per_pixel
        '0 c %s' % corner_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        'X c %s' % base_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        '- c %s' % light_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        '= c %s' % shadow_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        '* c %s' % highlight_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii')]

xpm += [s.strip() for s in ascii_led.splitlines()]

self.bmp = wx.Bitmap(xpm)

OG代码来自下面的代码,来自http://code.activestate.com/recipes/533125-wxpython-led-control/

# Based on C++ code by Thomas Monjalon
# Developed by Daniel Eloff on 14/9/07

import wx

def change_intensity(color, fac):
    rgb = [color.Red(), color.Green(), color.Blue()]
    for i, intensity in enumerate(rgb):
        rgb[i] = min(int(round(intensity*fac, 0)), 255)

    return wx.Color(*rgb)    

class LED(wx.Control):
    def __init__(self, parent, id=-1, colors=[wx.Colour(220, 10, 10), wx.Colour(250, 200, 0), wx.Colour(10, 220, 10)],
                 pos=(-1,-1), style=wx.NO_BORDER):
        size = (17, 17)
        wx.Control.__init__(self, parent, id, pos, size, style)
        self.MinSize = size

        self._colors = colors
        self._state = -1
        self.SetState(0)
        self.Bind(wx.EVT_PAINT, self.OnPaint, self)

    def SetState(self, i):
        if i < 0:
            raise ValueError, 'Cannot have a negative state value.'
        elif i >= len(self._colors):
            raise IndexError, 'There is no state with an index of %d.' % i
        elif i == self._state:
            return

        self._state = i
        base_color = self._colors[i]
        light_color = change_intensity(base_color, 1.15)
        shadow_color = change_intensity(base_color, 1.07)
        highlight_color = change_intensity(base_color, 1.25)

        ascii_led = '''
        000000-----000000      
        0000---------0000
        000-----------000
        00-----XXX----=00
        0----XX**XXX-===0
        0---X***XXXXX===0
        ----X**XXXXXX====
        ---X**XXXXXXXX===
        ---XXXXXXXXXXX===
        ---XXXXXXXXXXX===
        ----XXXXXXXXX====
        0---XXXXXXXXX===0
        0---=XXXXXXX====0
        00=====XXX=====00
        000===========000
        0000=========0000
        000000=====000000
        '''.strip()

        xpm = ['17 17 5 1', # width height ncolors chars_per_pixel
               '0 c None', 
               'X c %s' % base_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
               '- c %s' % light_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
               '= c %s' % shadow_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
               '* c %s' % highlight_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii')]

        xpm += [s.strip() for s in ascii_led.splitlines()]

        self.bmp = wx.BitmapFromXPMData(xpm)

        self.Refresh()

    def GetState(self):
        return self._state

    State = property(GetState, SetState)

    def OnPaint(self, e):
        dc = wx.PaintDC(self)
        dc.DrawBitmap(self.bmp, 0, 0, True)

【问题讨论】:

  • 欢迎来到 SO!查看tourHow to Ask。你有什么问题?你知道Python 2 and 3 handle strings totally differently吗?请edit这个问题有一个描述性的标题,并澄清你在问什么。 LMK 当你这样做时,我会撤消我的反对票。
  • 我的错,显然你在问如何解决它。不过,您仍然应该设置一个更好的标题。
  • 到底是什么问题?你做过调试吗?请提供minimal reproducible example,以及完整的错误消息。

标签: python python-2to3


【解决方案1】:

bytesstr 在 Python 2 中是同义词,但在 Python 3 中已成为不兼容的类型。wx.Bitmap 的构造函数需要一个字节列表,因此您应该确保传递给的列表中的每个项目它是一个 bytes 对象,通过使用字节文字或将字符串编码为字节:

xpm = [b'17 17 5 1', # width height ncolors chars_per_pixel
        b'0 c %s' % corner_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        b'X c %s' % base_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        b'- c %s' % light_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        b'= c %s' % shadow_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii'),
        b'* c %s' % highlight_color.GetAsString(wx.C2S_HTML_SYNTAX).encode('ascii')]

xpm += [s.strip().encode('ascii') for s in ascii_led.splitlines()]

【讨论】:

  • 嘿,感谢您的建议,我该如何完成呢?我上周开始学习 python,所以我有点挣扎。
  • 不客气。您是否尝试过我上面包含的代码示例?注意为每个字符串文字添加的 b 前缀以使其成为字节文字,并在最后一行添加对 encode 的调用。
  • 我没有注意到差异,我只是尝试了一下,它并没有改变它仍然说它需要一个字节列表的错误。谢谢你的帮助
【解决方案2】:

wx 上的文档并不清楚它希望如何准确地格式化此输入,但您可以尝试在将列表传递给Bitmap构造函数:

self.bmp = wx.Bitmap([s.encode() for s in xpm])

【讨论】:

  • 感谢您的帮助,我试过了,但它导致了一个系统错误,弹出了一个完整的错误,这比我的尝试变得如此酷。窗口显示,“XPM:格式错误的颜色定义 '0 c b#808080'' 在第 1 行!
【解决方案3】:

Bytes 对象在 Python 3 中有所不同。请参阅this documentation 页面。

【讨论】:

    【解决方案4】:

    您可以将字节字符串传递给 list() 以进行转换:

    list(bytes(xpm))
    

    【讨论】:

    • 感谢您的帮助它没有工作它导致“TypeError:'str'对象不能被解释为整数”
    猜你喜欢
    • 2019-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多