style query: function attributes for return codes?
gry at ll.mit.edu
Fri Dec 10 20:35:23 CET 2004
On Fri, 10 Dec 2004 16:40:25 GMT
Steven Bethard <steven.bethard at gmail.com> 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)
> >>> 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
> return cls.BAD_AUTH
> 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()
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 __init__(self, badauth=False, noserver=False):
self.badauth = badauth
self.noserver = noserver
return not(self.badauth and self.noserver)
ret = get_connection()
if not ret:
still seems a bit cumbersome in definition,
though the use is not bad...
"Are the gods not just?" "Oh no, child.
What would become of us if they were?" (CSL)
More information about the Python-list