Где находится объект повышения в Python? - PullRequest
0 голосов
/ 17 сентября 2010

Когда вы хотите напечатать несколько переменных в Python, у вас есть довольно много опций, таких как:

for i in range(len(iterable)):
    print iterable[i].name

ИЛИ

map(lambda i: sys.stdout.write(i.name), iterable)

Причина, по которой я использую sys.stdout.write вместо print во втором примере состоит в том, что lambdas не будет принимать print, но sys.stdout.write служит той же цели.

Вы также можете вывести условно с помощью тернарного оператора:

map(lambda n: None if n % 2 else sys.stdout.write(str(n)), range(1, 100))

Так что было бы очень удобно, если бы я мог проверить всю последовательность на наличие условия, которое будет оправдывать исключение таким способом:

map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)

Но это не работает.Есть ли такой объект для повышения в Python, и если да, то где он?

Ответы [ 4 ]

4 голосов
/ 17 сентября 2010

Не существует Python-объекта (встроенного или в стандартной библиотеке) для raise, вы должны создать его самостоятельно (типичный короткий фрагмент, который входит в util.py ...!):

def do_raise(exc): raise exc

обычно называется do_raise(InvalidObjectError(o.name)).

2 голосов
/ 17 сентября 2010

Я не думаю, что можно использовать raise в лямбде, как вы пытаетесь это сделать. raise - это выражение / выражение, а не объект. Как сказал @Alex Martelli, вам, вероятно, потребуется определить функцию, которая сделает проверку за вас. Теперь функция может быть объявлена ​​локально, в том же контексте.

Что касается типов исключений, то, на что, по-видимому, направлен ваш вопрос: типы исключений не определяются автоматически. Для простых типов исключений, когда вам нужно либо просто текстовое сообщение, либо его вообще нет, обычно типы исключений определяются просто в области вашего модуля / файла как:

class InvalidObjectError(Exception): pass
1 голос
/ 17 сентября 2010

Не. Не. Делать. Это.

Это ужасная идея.

map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)

Сделай это.

class SomeValidatingClass( object ):
    def isValid( self ):
        try: 
            self.validate()
        except InvalidObjectError:
            return False
        return True
    def validate( self ):
        """raises InvalidObjectErorr if there's a problem."""

[ x.validate() for x in iterable ]

Нет карты. Нет лямбды. Такое же поведение.

0 голосов
/ 17 сентября 2010

Для вашего первого примера я использую форму, подобную этой:

print '\n'.join(obj.name for obj in iterable)

Также я бы использовал:

firstnotvalid = next(obj.name for obj in iterable if not obj.is_valid())

И вместо:

>>> import sys
>>> map(lambda n: None if n % 2 else sys.stdout.write(str(n)), range(1, 100))
2468101214161820222426283032343638404244464850525456586062646668707274767880828486889092949698[None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None]

Я бы сделал:

>>> print (', '.join(str(number) for number in range(1,100) if not number % 2))
2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98

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

...