Python相当于PHP的@

时间:2011-05-15 05:21:25

标签: exception-handling python

是否有Python的等效PHP @

@function_which_is_doomed_to_fail();

我一直用这个块:

try:
  foo()
except:
  pass

但我知道必须有更好的方法。

有谁知道我如何将该代码进行Pythonic化?


我认为在该代码中添加一些上下文是合适的:

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)

6 个答案:

答案 0 :(得分:5)

你正在寻找的是反pythonic,因为:

  

Python的禅宗,蒂姆·彼得斯   美丽胜于丑陋   明确胜过隐含。
  简单比复杂更好   复杂比复杂更好   扁平比嵌套好。
  稀疏比密集更好   可读性很重要   特殊情况不足以违反规则。
  虽然实用性超过了纯度   错误绝不应该默默无闻   除非明确沉默。
  面对模棱两可,拒绝猜测的诱惑   应该有一个 - 最好只有一个 - 明显的方式来做到这一点   虽然这种方式起初可能并不明显,除非你是荷兰人   现在总比没有好。
  虽然现在永远不会比正确更好   如果实施很难解释,那是个坏主意   如果实施很容易解释,那可能是个好主意   命名空间是一个很棒的主意 - 让我们做更多的事情!

在你的情况下,我会使用这样的东西:

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

你有3行而不是4行。

答案 1 :(得分:2)

没有更好的方法。在任何语言中,默默地忽略错误都是不好的做法,所以它自然不是Pythonic。

答案 2 :(得分:1)

请不要让Python像PHP一样。您应始终明确捕获最具体的错误。捕捉并忽略所有这些错误并不是最佳实践。这是因为它可以隐藏其他问题并使bug更难找到。但是在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)

不需要尝试在此处捕获异常,因为没有异常。除了...当有类似错字引起的例外时。

答案 3 :(得分:1)

使用数据驱动设计而不是重复自己。命名相关组也可以更容易地避免组索引错误:

_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)

答案 4 :(得分:1)

基于Gabi Purcanu的回答以及您希望凝聚成一行的愿望,您可以将他的解决方案封装到一个函数中并减少您的示例:

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)

答案 5 :(得分:0)

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

编辑后:

您可能想在尝试获取组之前检查它是否不是None同时在组上使用len()来查看你有多少组。 “通过”错误绝对不是可行的方法。