Dove è l'oggetto rilancio in Python?
Domanda
Quando si desidera stampare un gruppo di variabili in Python, si hanno poche opzioni, come ad esempio:
for i in range(len(iterable)):
print iterable[i].name
o
map(lambda i: sys.stdout.write(i.name), iterable)
La ragione per l'uso che sys.stdout.write invece di stampa nel secondo esempio è quello lambda non accetteranno di stampa, ma sys.stdout.write serve allo stesso scopo.
È anche possibile stampare in modo condizionale con l'operatore ternario:
map(lambda n: None if n % 2 else sys.stdout.write(str(n)), range(1, 100))
Quindi sarebbe davvero utile se potessi controllare un'intera sequenza per una condizione che potrebbe giustificare un'eccezione in tal modo un:
map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)
Ma questo non funziona. C'è un tale oggetto per il rilancio in Python, e se sì, dove si trova?
Soluzione
Non c'è un "oggetto" Python (built-in o nella libreria standard) per raise
, è necessario costruire uno voi stessi (frammento tipica breve che va nella propria util.py
...!):
def do_raise(exc): raise exc
in genere di essere chiamato come do_raise(InvalidObjectError(o.name))
.
Altri suggerimenti
Non credo che sia possibile utilizzare raise
in un lambda, come si sta tentando di fare. raise
è una dichiarazione / espressione, non un oggetto. Come @alex Martelli ha dichiarato, faresti probabile necessità di definire una funzione per fare l'assegno per voi. Ora, la funzione potrebbe essere dichiarato localmente, all'interno dello stesso contesto.
Per quanto riguarda i tipi di eccezione, che è ciò che la tua domanda sembra essere finalizzato a: tipi di eccezione non sono definiti automaticamente. Per semplici tipi di eccezione, in cui si desidera sia solo un messaggio di testo, o del tutto assenti, di solito tipi di eccezione sono definiti semplicemente al vostro campo di applicazione del modulo / file come:
class InvalidObjectError(Exception): pass
Do. Non. Fare. Questo.
Questa è un'idea terribile.
map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)
Fate questo.
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 ]
nessuna mappa. No lambda. Lo stesso comportamento.
Per il primo modulo di utilizzo esempio che ho in questo modo:
print '\n'.join(obj.name for obj in iterable)
Anche io userei:
firstnotvalid = next(obj.name for obj in iterable if not obj.is_valid())
E invece di:
>>> 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]
Vorrei fare:
>>> 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
Ignorando che non c'è parametro passo per la gamma, come penso la funzione è la semplificazione di altre funzioni più complicate.