Reputation: 351
When you want to print a bunch of variables in Python, you have quite a few options, such as:
for i in range(len(iterable)):
print iterable[i].name
OR
map(lambda i: sys.stdout.write(i.name), iterable)
The reason I use sys.stdout.write instead of print in the second example is that lambdas won't accept print, but sys.stdout.write serves the same purpose.
You can also print conditionally with the ternary operator:
map(lambda n: None if n % 2 else sys.stdout.write(str(n)), range(1, 100))
So it would be really handy if I could check an entire sequence for a condition that would warrant an exception in such a way:
map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)
But that doesn't work. Is there such an object for raise in Python, and if so, where is it?
Upvotes: 0
Views: 1500
Reputation: 391862
Do. Not. Do. This.
This is a dreadful idea.
map(lambda o: raise InvalidObjectError, o.name if not o.isValid else o(), iterable)
Do this.
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 ]
No map. No lambda. Same behavior.
Upvotes: 1
Reputation: 5555
For your first example I use form like this:
print '\n'.join(obj.name for obj in iterable)
Also I would use:
firstnotvalid = next(obj.name for obj in iterable if not obj.is_valid())
And instead of:
>>> 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]
I would do:
>>> 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
Ignoring that there is step parameter for range, as I think the function is simplification of other more complicated functions.
Upvotes: 0
Reputation: 4590
I don't think it's possible to use raise
in a lambda, like you're attempting to do. raise
is a statement/expression, not an object. As @Alex Martelli has stated, you'd likely need to define a function to do the check for you. Now, the function could be declared locally, within the same context.
As far as the exception types, which is what your question seems to be aimed at: Exception types are not defined automatically. For simple exception types, where you either want just a text message, or none at all, typically exception types are defined simply at your module/file scope as:
class InvalidObjectError(Exception): pass
Upvotes: 2
Reputation: 881805
There is no Python "object" (built-in or in the standard library) for raise
, you have to build one yourself (typical short snippet that goes in one's util.py
...!):
def do_raise(exc): raise exc
typically to be called as do_raise(InvalidObjectError(o.name))
.
Upvotes: 4