2010-09-17 14 views
0

Lorsque vous voulez imprimer un tas de variables en Python, vous avez tout à fait quelques options, telles que:Où est l'objet raise en Python?

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

OU

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

La raison pour laquelle j'utilise sys.stdout.write au lieu de print dans le second exemple est que lambdas n'acceptera pas l'impression, mais sys.stdout.write sert le même but.

Vous pouvez également imprimer sous condition avec l'opérateur ternaire:

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

Il serait vraiment pratique si je pouvais vérifier une séquence entière pour une condition qui justifierait une exception de telle manière:

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

Mais cela ne fonctionne pas. Existe-t-il un tel objet pour relancer en Python, et si oui, où est-ce?

+1

-1: Wow c'est tout mauvais. S'il vous plaît ne jouez pas au golf de code comme ça. Merci de ne pas rendre Python illisible. Quel est le problème avec le premier style? Cela avait du sens. Pourquoi utiliser des techniques de cartes bizarres qui rendent les choses obscures? Quel est le but de toute cette obscurité? Ce ne sera pas plus rapide. Ce ne sera pas plus facile à lire. Pourquoi faire ceci? –

+0

@S. Lott les deux premiers exemples de cartes sont certes inutiles, mais ils étaient seulement pour démontrer sys.stoud.write et la façon dont je veux utiliser augmenter. Mais je ne vois pas pourquoi la troisième carte serait mauvaise si c'était possible. – cory

+0

Pourquoi utiliser 'sys.stdout.write' quand vous pouvez utiliser' from __future__ import print_function'? –

Répondre

4

Il n'y a pas Python « objet » (intégré ou dans la bibliothèque standard) pour raise, vous devez construire un vous-même (extrait typique court qui va dans son util.py ...!):

def do_raise(exc): raise exc 

généralement appelé do_raise(InvalidObjectError(o.name)).

+0

Je crie sous le nom 'do_raise' – Gabe

+2

La façon classique d'utiliser un mot-clé Python comme identifiant serait' raise_'. –

+0

@Gabe: Peut-être que vous devriez reculer devant une situation pour laquelle c'est la réponse acceptée. –

2

Je ne pense pas qu'il soit possible d'utiliser raise dans un lambda, comme vous essayez de le faire. raise est une déclaration/expression, pas un objet. Comme l'a déclaré @Alex Martelli, vous aurez probablement besoin de définir une fonction pour faire le contrôle pour vous. Maintenant, la fonction pourrait être déclarée localement, dans le même contexte.

En ce qui concerne les types d'exception, ce à quoi votre question semble destinée: Les types d'exception ne sont pas définis automatiquement. Pour de simples types d'exception, où vous voulez, soit juste un message texte, ou pas du tout, généralement les types d'exception sont définis simplement à votre module/champ de fichier comme:

class InvalidObjectError(Exception): pass 
+0

En fait, la première partie de votre réponse est correcte, je voulais savoir s'il y avait un objet pour l'instruction raise comme pour l'instruction print. – cory

+0

"Je ne pense pas qu'il soit possible d'utiliser raise dans un lambda, comme vous essayez de le faire, raise est une expression/expression, pas un objet." On pourrait argumenter que cela signifie que python n'est pas assez fonctionnel. – g33kz0r

0

Pour votre premier exemple que je forme comme ceci:

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

Je voudrais aussi utiliser:

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

Et au lieu de:

>>> 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] 

je ferais:

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

sans tenir compte qu'il ya paramètre pas pour la plage, comme je pense que la fonction est la simplification des autres fonctions plus complexes.

1

Do. Ne pas. Faire. Ce.

C'est une idée épouvantable.

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

Faites ceci.

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 ] 

Aucune carte. Pas de lambda. Même comportement

+0

Qu'est-ce qui ne va pas avec map et lambda? Il me semble que vous recommanderiez également d'utiliser une boucle for et une instruction if au lieu de filter(), ce qui sert (à mes yeux) à extraire le processus. – cory

+0

@cory: le filtre est difficilement comparable à cela. L'utilisation de 'lambda' pour tenter de déclencher une exception est trop complexe. Pas un commentaire sur le filtrage. Seulement commenter sur votre cas d'utilisation exact. La validation réelle est beaucoup, beaucoup plus simple ici. Pas de carte. Non Lambda. '[x.validate() pour x dans itérable]'. Et votre exception est levée si un objet est invalide. Terminé. Pas de carte Non Lambda. –