On Tue, 15 Aug 2006 16:04:12 -0700, tobiah wrote: > Suppose I do: > > > myfoo = Foo('grapes', 'oranges') > > And in the __init__() of Foo, there is > a real problem with the consumption of fruit. > Is there a clean way to ensure that myfoo > will be None after the call?
I don't believe so. Generally, in the event of an error, you should raise an exception: class Foo(): def __init__(self, *fruits): if "grapes" in fruits: raise AllergyError("I'm allergic to grapes") # process fruits Then handle the exception: try: myfoo = Foo('grapes', 'oranges') except AllergyError: # recover gracefully handle_failed_instance() If you wish, you can wrap it in a function: def safe_foo(*fruits): try: return Foo(*fruits) except AllergyError: return None myfoo = safe_foo('grapes', 'oranges') The disadvantage of this is now your code has to be sprinkled with a million tests "if myfoo is not None: process(myfoo)". > Would the > __init__() just do del(self), or is there > a better way to think about this? An alternative is to use a propagating "not a Foo" Foo object, like NaNs and INFs in floating point. class Foo(): def __init__(self, *fruits): if "grapes" in fruits: self._state = "failed" # NaNs use special bit patterns else: # process fruits self._state = "okay" def method(self, *args): if self._state != "failed": # process instance else: pass # do nothing def __add__(self, other): if self._state == "failed": return self elif other._state == "failed": return other else: # process Foo addition return something Now you can call Foo methods regardless of whether the instance is valid or not, errors will propagate cleanly, and you only need to check whether the instance is valid at the very end of your code. However, unless there is a clear advantage of doing this, you're creating a fair bit of extra work for yourself. -- Steven D'Aprano -- http://mail.python.org/mailman/listinfo/python-list