2017-01-17 4 views
-1

私はircボットを作っており、たくさんのスクリプトが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()] 

、結果にバイトを呼び出すと、型エラーがスローされます...と思った:

>>> 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')に変更するのは簡単ですが、なぜですか?それから、結果に__str__を追加し、任意の引数をxに変換するCPU時間を無駄にする必要があります。

__int__などの組み込み関数も、文字列をintに変換するための引数baseを受け入れるようにしました。しかし、__bytes__のように、TypeError: int() can't convert non-string with explicit baseもスローされます。エラーメッセージは明白であり、繰り返します:私はなぜそれがエラーを投げているのか尋ねていません。 __str__または__bytes__または__int__のようなものを組み込み関数として機能させるために、フープを飛び越さなければならないという背後にあるロジックは何であるかを尋ねています。

+1

Umm、申し訳ありませんが、なぜ 'bytes(r、encoding = 'utf-8')'が 'r'を' str'にする必要があるのですか?たぶん何か他のものをエンコーディングするのは本当に意味をなさないからです。 'encoding'引数にもかかわらず、' bytes'の 'bytes'をアイデンティティにしますか?私はそれがデザインの決定だと思う。ユーザーは無意識のうちに何かをしようとするか、間違っているのか、それとも無視しますか? Btw。これがあなたの問題なら '__str__'を提供する必要はありません。あなたの問題に対して「回避策」/ソリューションを投稿することができます。 – luk32

+0

@ luk32 3番目のオプション(これはPHPが何回かの時間を費やすものです):ユーザの混乱を招き予期しない結果を返すことがあります。 –

+1

@leafこれはJSの方法だと思った。失敗はオプションではありません。 =] – luk32

答えて

1

私が正しく理解していれば、bytesencodingは同一性機能として機能しないという問題があります。

bytesstrに再エンコードするように強制されていると思われますが、そうではありません。バイトをエンコードしようとする必要はありません。

は、あなたのニーズに合わせて機能を拡張しまう小さなヘルパー関数を記述することによって、それを回避することができます。これは、あなたが期待する正確に何である

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' 

。少なくともバイトと文字列の場合。私はあなたがすべてのタイプを扱う必要がある場合は、ロジックが少し複雑になるだろうと思うが、それほど多くはない。

関連する問題