Python эквивалент PHP - PullRequest
       2

Python эквивалент PHP

0 голосов
/ 15 мая 2011

Есть ли Python-эквивалент PHP @?

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

Ответы [ 6 ]

5 голосов
/ 15 мая 2011

То, что вы ищете, является анти-пифоническим, потому что:

Дзен Питона, Тим Питерс
Красиво лучше, чем некрасиво.
Явное лучше, чем неявное.
Простое лучше, чем сложное.
Сложный лучше, чем сложный.
Квартира лучше, чем вложенная.
Разреженный лучше, чем плотный.
Читаемость имеет значение.
Особых случаев недостаточно, чтобы нарушать правила.
Хотя практичность превосходит чистоту.
Ошибки никогда не должны проходить бесшумно.
Если явно не молчать.
Перед лицом двусмысленности откажитесь от искушения угадать.
Должен быть один - и желательно только один - очевидный способ сделать это.
Хотя этот путь может быть неочевидным, если вы не голландец.
Теперь лучше, чем никогда.
Хотя никогда не бывает лучше, чем прямо сейчас.
Если реализацию сложно объяснить, это плохая идея.
Если реализацию легко объяснить, это может быть хорошей идеей.
Пространства имен - это одна из отличных идей - давайте сделаем больше!

В вашем случае я бы использовал что-то вроде этого:

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

И у вас есть 3 строки вместо 4.

2 голосов
/ 15 мая 2011

Нет лучшего способа. Молчаливое игнорирование ошибок - это плохая практика на любом языке, поэтому, естественно, это не Pythonic.

1 голос
/ 17 мая 2011

Опираясь на ответ Габи Пуркану и ваше желание сконцентрироваться на однострочниках, вы можете заключить его решение в функцию и сократить свой пример:

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)
1 голос
/ 15 мая 2011

Используйте управляемый данными дизайн вместо повторения. Присвоение имени соответствующей группе также позволяет избежать ошибок индексации группы:

_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)
1 голос
/ 15 мая 2011

Пожалуйста, не просите 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 голосов
/ 15 мая 2011

В Python есть контроль предупреждений - http://docs.python.org/library/warnings.html

После редактирования:

Возможно, вы хотите проверить, не является ли это None, прежде чем пытаться получить группы. Также используйте len () для групп, чтобы увидеть, сколько у вас групп . «Передача» ошибки - определенно не тот путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...