On Fri, 10 Dec 2004 16:40:25 GMT Steven Bethard <[EMAIL PROTECTED]> threw this fish to the penguins:
> george young wrote: > > This is obviously just evil, since a misspelling in the string > > return is treacherous. I'm considering function attributes: > > > > def get_connection(): > > if tcp_conn(): > > if server_allows_conn(): > > return get_connection.GOOD > > else: > > return get_connection.BAD_AUTH > > else: > > return get_connection.NO_SERVER > > get_connection.GOOD = 1 > > get_connection.BAD_AUTH = 2 > > get_connection.NO_SERVER = 3 > > Although in most cases this is probably okay, you're not guaranteed that > the name of your function will stay the same, so there are some hazards > in this style: > > >>> def f(x): > ... return f.y * x > ... > >>> f.y = 100 > >>> f(2) > 200 > >>> g, f = f, None > >>> g(2) > Traceback (most recent call last): > File "<interactive input>", line 1, in ? > File "<interactive input>", line 2, in f > AttributeError: 'NoneType' object has no attribute 'y' Yes, I was worried about this. > One option is to turn your function into a class: > > class get_connection(object): > GOOD = 1 > BAD_AUTH = 2 > NO_SERVER = 3 > def __new__(cls): > if tcp_conn(): > if server_allows_conn(): > return cls.GOOD > else: > return cls.BAD_AUTH > else: > return cls.NO_SERVER > > This is a little sneaky here -- because you only need shared state > between all instances of get_connection, you don't actually ever need to > create an instance. So I've overridden __new__ to return the result of > the function instead. This allows you to call the function just like > you would have before. I haven't tested the code above, but here's a > simpler example that works: > > >>> class look_ma_no_function(object): > ... X = 42 > ... def __new__(cls): > ... return cls.X > ... > >>> look_ma_no_function() > 42 Hmm, this is quite clever, and indeed does what I want. I hesitate to adopt it, though, because it *looks* sneaky. For readable and maintainable code, I think it may be a bit too hackish... The original impetus for my post was to find a clear, maintainable form. I wonder about returning an object that tests True if all is ok, and has boolean attributes to query if not True...: def get_connection(): class Ret: def __init__(self, badauth=False, noserver=False): self.badauth = badauth self.noserver = noserver def __nonzero__(self): return not(self.badauth and self.noserver) if tcp_conn(): if server_allows_conn(): return Ret() else: return Ret(badauth=True) else: return Ret(noserver=True) ret = get_connection() if not ret: if ret.badauth: ... still seems a bit cumbersome in definition, though the use is not bad... -- George -- "Are the gods not just?" "Oh no, child. What would become of us if they were?" (CSL) -- http://mail.python.org/mailman/listinfo/python-list