2017-10-21 27 views
1

我的具體問題是

  1. 當解析一個參數,它是直觀未來的維護者理解代碼依賴於拋出一個錯誤?
  2. 默認情況下拋出異常是否很昂貴? (好像它可能根據https://stackoverflow.com/a/9859202/776940

語境

我有一個參數counter其確定計數器的名稱來遞增,並且任選地可以通過從計數器分離的正或負整數遞增名字由=。如果沒有提供增值,增量的默認大小爲1。功能是通過破壞一個逗號分隔的計數器和增量的名單反饋的信息,有效的投入到整個過程是這樣的:解析參數字符串時PyEronic是否依賴ValueError?

"counter1,counter2=2,counter3=-1" 

這將增加「C1的」加1,加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) 

它給我的印象,因爲我最近回到2和減量「C3的」增量「計數器2」看看它,過於冗長和笨重。

這是一個或多或少Pythonic的方式來編碼的行爲?

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

利用這些測試用例,我看到:

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

,將已陷入我最初是如何寫的(上述)這些測試案例不會陷入這樣:

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

這個最後的測試案例並沒有被任何一種方法所捕獲。無論做int()嘔吐:

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

我很高興我問這個問題,發現了這個問題。消耗這個值的服務最終會扼殺它。我想我可以在函數的一行return desc, int(mag)更改此設置:

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 

(帽尖到https://stackoverflow.com/a/9859202/776940搞清楚,這是在討論提供了最快的方式確定一個字符串爲整數)

+1

我只會考慮處理ValueErrors或這種情況下,如果解析對象可能會失敗。它在這裏被使用的方式只是因爲你獲得的列表不能被解壓縮。我不會認爲它pythonic。同樣的原因,如果我們知道我們正在處理「無」值時,我們就不應該處理AttributeErrors。 –

+0

@JeffMercado如果參數默認爲'increment = 1',並且完全脫離等於,或者參數格式錯誤(例如,多個等於或在增量中帶有非數字字符或如果完整的參數串缺少兩個計數器值之間的逗號)。我最初的做法是明確解析和測試,而且我錯過了'foo = 3bar = 5'的單元測試用例,在'bar'之前應該有一個逗號。感謝您的反饋。 –

回答

2

我認爲Python的,雖然你也許對這喜歡:

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.rsplit而不是counter.split