1

Recently I've found myself using the following idiom in some of my functions:

[...] def validate(self): # Possibly do something "expensive" to calculate whether data is valid or not if data_is_valid: return ObjectOfSomeSort(validated_data) return False ret = self.validate() if ret: return ret [...] 

I feel like the ret = ...; if ret: return ret syntax is a little unwieldy and unpythonic, however, and I'm not always able to do something like

if self.validate(): return self.validate() 

because occasionally my validation functions contain some rather computationally expensive logic.

So, StackOverflow, what python idioms exist for this sort of problem; specifically, how else can I "conditionally return"?

5
  • I must agree, is totally unpythonic because I actually don't get what are you trying to do... If it is hard to explain, it's a bad idea :P Commented Feb 8, 2013 at 15:38
  • My "validation" function returns False if the data is invalid. If the data is valid, I'd like to bail out of the calling function early (the one that calls self.validate()); if it is not I would like to continue on the execution flow. Commented Feb 8, 2013 at 15:40
  • Hm, it seems that the semantics are a bit wrong here: self.validate() implies that you want to make sure that the current(!) object, aka self is valid. Commented Feb 8, 2013 at 15:41
  • Yeah, you're right -- this is what my code does -- however I'm perhaps a little overtired and did a poor job of articulating myself. Commented Feb 8, 2013 at 15:42
  • 1
    The name of the method is clearly wrong. I'd expect validate to return True if the object is valid and False otherwise. Commented Feb 8, 2013 at 15:46

4 Answers 4

2

Idiomatic in Python is to use an exception.

 class InvalidDataError(Exception): pass def get_valid_object(): if not data_is_valid: raise InvalidDataError() return ObjectOfSomeSort(validated_data) 

And then to use it:

 try: valid_object = get_valid_object() except InvalidDataError: ... handle error 
Sign up to request clarification or add additional context in comments.

1 Comment

An exception is something I'd completely forgotten about; thanks!
1

You could do

def ifloop(x): if x: yield x for ret in ifloop(self.validate()): return ret 

4 Comments

I think I'd take the if block first ;-). But interestingly clever use of a generator function.
+1 for the clever generator; these are the sorts of answers I'm looking for ;)
That's a NameError at runtime.
Only insofar as "y is not defined"; the snippet of code my original question posted would also NameError for the same reason. It's pretty tangential to the point of the answer, though.
0

If the code doesn't need to continue after your if, I'd write:

return self.validate() or None 

2 Comments

I like this, even though a non-python program might be puzzled.
This will either return self.validate() or return None if self.validate() is non-True; I'd like the non-True case to continue along executing (i.e. the return statement is never triggered)
0

You could use the NULL object pattern, making sure to add the following method so instances of it will be also be considered False -- which will make testing for it easier:

def __nonzero__(self) : return False 

The usefulness of such Null objects is that they can be used like almost any other object so in many case you won't have to check for them in the rest of your code which can assume it's got a valid object of some other type.

I first heard about this pattern in the second edition of the Python Cookbook by Alex Martelli. It's recipe 6.17

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.