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'
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
If you need to do this with a function that takes more parameters, you can just add them to the __new__ declaration:
>>> class look_ma_no_function(object): ... X = 42 ... def __new__(cls, s): ... return cls.X / float(len(s)) ... >>> look_ma_no_function('answer to life the universe and everything') 1.0
Despite the fact that this particular use seems a little sneaky to me, I do usually end up turning most functions that seem to need attributes into classes (usually with a __call__ method defined).
Steve -- http://mail.python.org/mailman/listinfo/python-list