2017-10-21 3 views
1

私の具体的な懸念は、それがエラーをスローに依存したコードを理解するために、将来のメンテナのための直感的で、

をしていますか?
  • デフォルトのケースでは例外として例外をスローするのは費用がかかりますか? Iがインクリメントするカウンタの名前を決定するパラメータcounterを有し、必要に応じてカウンタから分離正または負の整数をインクリメントすることができる(それはhttps://stackoverflow.com/a/9859202/776940に従ってれるかもしれないように思える)
  • コンテキスト

    =で指定します。何のインクリメント値が提供されていない場合は、増分のデフォルトの大きさは、1関数であるカウンタと増分のカンマ区切りのリストを分割することで供給され、そのプロセス全体への有効な入力は次のように見ることができます:パラメータストリングの解析時にValueErrorに依存するのはPythonicですか?パラメータを解析するとき

    "counter1,counter2=2,counter3=-1" 
    
    私は最近戻ってきたように私はもともと、それに私を打つ
    counterDescriptor = counterValue.split('=') 
    if len(counterDescriptor) == 1: 
        counterName = counterDescriptor[0] 
        counterIncr = 1 
    elif len(counterDescriptor) == 2: 
        counterName = counterDescriptor[0] 
        counterIncr = int(counterDescriptor[1]) 
    else: 
        counterName, counterIncr = ('counterParsingError', 1) 
    

    を書い方法1.

    によって2で1、インクリメント「カウンタ2」で「カウンタ」をインクリメントとデクリメント「COUNTER3」でしょう

    それを見て、過度に冗長で不器用です。

    これは多かれ少なかれ、その動作をコード化するPythonの方法ですか?これらのテストケースでは

    def cparse(counter): 
        try: 
         desc,mag = counter.split('=') 
        except ValueError: 
         desc = counter 
         mag = '' 
        finally: 
         if mag == '': 
          mag = 1 
        return desc, int(mag) 
    

    、私は以下を参照してください。

    >>> cparse("twoEquals=2=3") 
    ('twoEquals=2=3', 1) 
    >>> cparse("missingComma=5missingComma=-5") 
    ('missingComma=5missingComma=-5', 1) 
    

    >>> cparse("byfour=4") 
    ('byfour', 4) 
    >>> cparse("minusone=-1") 
    ('minusone', -1) 
    >>> cparse("equalAndNoIncr=") 
    ('equalAndNoIncr', 1) 
    >>> cparse("noEqual") 
    ('noEqual', 1) 
    

    私はもともと(上記)それを書いた方法をキャッチされていたであろうこれらのテストケースは、この方法で捕まるません。

    この最後のテストケースは、どちらの方法でも検出されません。どちらも、int()嘔吐物を作る:

    >>> cparse("YAmissingComma=5NextCounter") 
    ValueError: invalid literal for int() with base 10: '5NextCounter' 
    

    私はこの質問を尋ねることによって、この問題を発見してくれてうれしいです。この値を消費するサービスは、最終的にそれを脅かすでしょう。 (これは文字列が整数であるかどうかを判断するという議論で提供最速の方法だったことを考え出すためhttps://stackoverflow.com/a/9859202/776940に帽子の先端)

    if desc.find("=")<0 and (mag=='0' or (mag if mag.find('..') > -1 else mag.lstrip('-+').rstrip('0').rstrip('.')).isdigit()): 
         return desc, int(mag) 
        else: 
         return 'counterParsingError: {}'.format(desc), 1 
    

    :私はこれに機能の1行 return desc, int(mag)を変えることができると仮定します
    +1

    オブジェクトの解析が失敗する可能性がある場合は、ValueErrorsまたはこのケースを処理することのみを検討します。それがここで使用されている方法は、あなたが得たリストを解凍することができなかったためです。私はそれをpythonicとは考えません。私たちが 'None'値を扱っていることが分かっているのであれば、それがテストできるだけの理由でAttributeErrorsを処理してはならないのと同じ理由があります。 –

    +0

    @JeffMercadoパラメータがデフォルトで 'increment = 1'になっていて、equalsから完全に離れる場合、またはパラメータが不正な場合(たとえば、2つ以上の等号がある場合、または増分またはパラメータの完全な文字列に2つのカウンタ値の間にコンマがない場合)。私が最初に行ったのは明示的に解析してテストしていたので、 'foo = 3bar = 5'のユニットテストケースがなくなっていましたが、 'bar'の前にカンマがあるはずです。フィードバックをお寄せいただきありがとうございます。 –

    答えて

    2

    あなたはおそらく好むかもしれませんが、私は、そのニシキヘビを検討する:

    def cparse(counter): 
        if "=" not in counter: 
         # early exit for this expected case 
         return (counter, 1) 
        desc, mag = counter.split("=", maxsplit=1) 
        # note the use of the optional maxsplit to prevent ValueErrors on "a=b=c" 
        # and since we've already tested and short-circuited out of the "no equals" case 
        # we can now consider this handled completely without nesting in a try block. 
        try: 
         mag = int(mag) 
        except ValueError: 
         # can't convert mag to an int, this is unexpected! 
         mag = 1 
        return (desc, mag) 
    

    あなたはa=b=cのような文字列を解析しながら、あなたは右の出力を得ることを確認するために、これを微調整することができます。 ('a', 1)を受け取ると予想される場合は、そのままコードを保管してください。 ('a=b', 1)が必要な場合はcounter.splitの代わりにcounter.rsplitを使用できます。

    関連する問題