2011-05-15 180 views
0

是否有PHP的@的Python等價物?Python的等價物@

@function_which_is_doomed_to_fail(); 

我一直使用此塊:

try: 
    foo() 
except: 
    pass 

但我知道必須有一個更好的辦法。

有誰知道我該如何Pythonicify該代碼?


我想添加一些上下文的代碼將是適當的:

for line in blkid: 
    line = line.strip() 
    partition = Partition() 

    try: 
    partition.identifier = re.search(r'^(/dev/[a-zA-Z0-9]+)', line).group(0) 
    except: 
    pass 

    try: 
    partition.label = re.search(r'LABEL="((?:[^"\\]|\\.)*)"', line).group(1) 
    except: 
    pass 

    try: 
    partition.uuid = re.search(r'UUID="((?:[^"\\]|\\.)*)"', line).group(1) 
    except: 
    pass 

    try: 
    partition.type = re.search(r'TYPE="((?:[^"\\]|\\.)*)"', line).group(1) 
    except: 
    pass 

    partitions.add(partition) 

回答

1

大樓和你的願望凝結成單行,你可以封裝他的解決方案成爲功能,減少您的例子:

def cond_match(regexp, line, grp): 
    match = re.search(regexp, line) 
    if match: 
     return match.group(grp) 
    else: 
     return None 

for line in blkid: 
    line = line.strip() 
    partition = Partition() 
    partition.identifier = cond_match(r'^(/dev/[a-zA-Z0-9]+)', line, 0) 
    partition.label = cond_match(r'LABEL="((?:[^"\\]|\\.)*)"', line, 1) 
    partition.uuid = cond_match(r'UUID="((?:[^"\\]|\\.)*)"', line, 1) 
    partition.type = cond_match(r'TYPE="((?:[^"\\]|\\.)*)"', line, 1) 
    partitions.add(partition) 
+0

好吧,我猜這樣做可以達到我猜想的那麼好。謝謝! – Blender 2011-05-16 22:29:05

5

你所尋找的是抗Python的,因爲:

的Python的禪,由蒂姆·彼得斯
美麗勝於醜陋。
顯式優於隱式。
簡單勝過複雜。
複雜比複雜更好。
平面比嵌套更好。
稀疏比密集好。
可讀性計數。
特殊情況不足以破壞規則。
雖然實用性勝過純度。
錯誤不應該默默通過。
除非明確沉默。
面對歧義,拒絕猜測的誘惑。
應該有一個 - 最好只有一個 - 明顯的方法來做到這一點。
雖然這種方式可能並不明顯,除非你是荷蘭人。
現在比永遠好。
雖然從來沒有好過現在
如果實施難以解釋,這是一個壞主意。
如果實現很容易解釋,這可能是一個好主意。
命名空間是一個重要的想法 - 讓我們做更多的這些!

在你的情況,我會用這樣的:

match = re.search(r'^(/dev/[a-zA-Z0-9]+)', line) 
if match: 
    partition.identifier = match.group(0) 

而且你有3條線,而不是4

+0

看我的編輯。也許你可以看到是否會有更好的解決方案來解決我的問題,因爲我很困惑它。 – Blender 2011-05-15 05:33:53

+0

感謝您的編輯。任何方式我可以凝聚成一個? – Blender 2011-05-15 05:50:21

+0

'partition.identifier = getattr(re.search(r'^(/ dev/[a-zA-Z0-9] +)',line),'group',[None])[0]' – Imran 2011-05-15 06:05:01

2

有沒有更好的辦法。在任何語言中默默地忽略錯誤都是不好的習慣,所以它自然不是Pythonic。

0

在Python警告控制 - http://docs.python.org/library/warnings.html

編輯後:

你可能要檢查,如果它不是None試圖讓組之前。 也可以在組上使用len()來查看你有多少組 。 「通過」錯誤絕對不是要走的路。

+0

I' d必須以某種方式緩存變量來引用並檢查'not None',然後使用'.group()',所以這對代碼長度沒有多大幫助。 – Blender 2011-05-15 05:34:46

+0

不需要'len()',因爲組數取決於正則表達式;它將沒有或表達式中的組數。 – 2011-05-15 05:36:55

+0

@Gabi Purcaru - 要點 – manojlds 2011-05-15 05:40:40

1

請不要要求Python像PHP一樣。您應該始終明確地捕獲可能的最具體的錯誤。捕捉並忽略所有類似的錯誤並不是最佳實踐。這是因爲它可以隱藏其他問題,使得找到更難的東西。但是在RE的情況下,你應該檢查它返回的None值。例如,你的代碼:

label = re.search(r'LABEL="((?:[^"\\]|\.)*)"', line).group(1) 

引發一個AttributeError如果沒有匹配,因爲re.search返回None如果沒有匹配。但是,如果有一個比賽,但你必須在你的代碼一個錯字:

label = re.search(r'LABEL="((?:[^"\\]|\.)*)"', line).roup(1) 

這也引發了一個AttributeError,即使是比賽。但是使用catchall異常並忽略它會掩蓋你的錯誤。在這種情況下,您永遠不會匹配標籤,直到您找到其他方式,例如最終注意到您的代碼永遠不會匹配標籤(但希望您已針對該情況進行單元測試...),您永遠不會知道它。

對於RE上,通常的模式是這樣的:

matchobj = re.search(r'LABEL="((?:[^"\\]|\.)*)"', line) 
if matchobj: 
    label = matchobj.group(1) 

沒有必要去嘗試,在這裏捕捉異常,因爲不會有一個。除了......當類似的拼寫錯誤導致異常時。

+0

對,如果Python有一種設置變量並同時檢查相等性的方法,比如'if(i = 0)和(i> foo)',我會使用它。我更擔心可讀性,但由於此解決方案很短,我現在就使用它。謝謝! – Blender 2011-05-15 05:49:51

+0

謝謝。但是爲了可讀性,Python可能沒有這個特性。 ;-)它也是語言錯誤的常見來源。 – Keith 2011-05-15 05:54:50

+0

噢,好的。現在,我認爲兩條線足夠好。我會看看我能做什麼。 – Blender 2011-05-15 05:55:30

1

使用數據驅動設計而不是重複自己。命名相關組也使得它更容易避免組索引錯誤:在加比Purcanu的回答

_components = dict(
    identifier = re.compile(r'^(?P<value>/dev/[a-zA-Z0-9]+)'), 
    label = re.compile(r'LABEL="(?P<value>(?:[^"\\]|\\.)*)"'), 
    uuid = re.compile(r'UUID="(?P<value>(?:[^"\\]|\\.)*)"'), 
    type = re.compile(r'TYPE="(?P<value>(?:[^"\\]|\\.)*)"'), 
) 

for line in blkid: 
    line = line.strip() 
    partition = Partition() 

    for name, pattern in _components: 
     match = pattern.search(line) 
     value = match.group('value') if match else None 
     setattr(partition, name, value) 

    partitions.add(partition)