2011-05-15 151 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)