我正在创建一个irc bot,并且大量的脚本会将符合f'{label}: {value}'
格式的内容返回。所以我创建了一个Result类并给它__bytes__
方法,因为我以前使用它并且它工作正常。或者我认为......
WHITE = '00'
BLACK = '01'
DARK_BLUE = '02'
DARK_GREEN = '03'
RED = '04'
DARK_RED = '05'
PURPLE = '06'
ORANGE = '07'
YELLOW = '08'
GREEN = '09'
TEAL = '10'
CYAN = '11'
BLUE = '12'
PINK = '13'
GREY = GRAY = '14'
def colorize(msg, color):
"""Add color code to message"""
return f'{color}{msg}'
class Result:
def __init__(self, label, value, color=RED):
self.repr = f'{colorize(label, color)}: {value}'
def __bytes__(self, encoding='utf-8'):
return self.repr.encode(encoding)
def join_results(results, sep=' '):
"""Break results into a maximum of 350 bytes per line"""
sep = sep.encode() if isinstance(sep, str) else sep
if not isinstance(sep, bytes):
raise TypeError('sep must be bytes or str')
if (not isinstance(results, list)) or (not results):
return []
seplen = len(sep)
x = bytes(results[0], encoding='utf-8')
ret = []
for result in results[1:]:
y = bytes(result)
msglen = len(y) + len(x)
if (msglen + seplen) > 350:
ret.append(x.decode())
x = y
else:
x = sep.join((x, y))
return ret + [x.decode()]
在上面的代码中,调用Result上的字节会引发类型错误:
>>> bytes(r, encoding='utf-8')
Traceback (most recent call last):
File "<pyshell#265>", line 1, in <module>
bytes(r, encoding='utf-8')
TypeError: encoding without a string argument
有些情况下,我希望join_results
也可以处理字符串列表。将join_results中的x更改为x = bytes(str(results[0]), encoding='utf-8')
而不是x = bytes(results[0], encoding='utf-8')
很简单,但为什么呢?然后我将不得不将__str__添加到Result并浪费cpu时间将任何参数转换为x字符串。
我还检查了其他内容,例如__int__
,其内置函数也接受base
参数将字符串转换为int。但与__bytes__
一样,它也会抛出TypeError: int() can't convert non-string with explicit base
。错误消息是明确的,所以要重申:我不是在问为什么它会抛出错误。我问的是,为了使__str__
或__bytes__
或__int__
之类的东西像内置函数那样工作,被迫跳过箍的逻辑是什么。
答案 0 :(得分:1)
如果我理解正确,则会遇到bytes
encoding
bytes
不能作为身份功能使用的问题。
您认为您被迫将str
转换为coerce_to_bytes = lambda x: x if isinstance(x, bytes) else bytes(x, encoding='utf-8')
s = "foo"
b = b"bar"
print(coerce_to_bytes(s), coerce_to_bytes(b))
>>> b'foo' b'bar'
只是为了重新编码,但事实并非如此。您只需要尝试编码字节。
你可以通过编写一个小帮助函数来解决它,它可以扩展功能以满足你的需求:
{{1}}
这正是您所期望的。至少对于字节和字符串。我想如果你需要处理所有类型,那么逻辑会有点复杂,但不是那么多。