Suggestions for good programming practices?
Bengt Richter
bokr at oz.net
Tue Jun 25 20:53:22 EDT 2002
On 25 Jun 2002 17:49:38 -0400, aahz at pythoncraft.com (Aahz) wrote:
>In article <afafee$fc$0 at 216.39.172.122>, Bengt Richter <bokr at oz.net> wrote:
>>
>>Do you recommend using def foo(*args) and testing len(args) instead?
>
>Only if you really want a list of unnamed parameters. Personally, I
>usually prefer to pass a sequence directly in such cases, to distinguish
>between None (i.e. no list) and the empty list.
Well, I meant using *args to allow detecting actual "no default-overriding
argument passed", in place of x=None. The arg list items (only x here)
don't have to remain unnamed long. E.g.,
>>> def foo(*args):
... if len(args)==1:
... print "We know we have one non-default arg: %s" % `args[0]`
... x = args[0]
... elif len(args)==0:
... print "We can supply a default arg, even None"
... x = None
... else: raise TypeError,'foo() takes 0 or 1 arguments (%d given)' % len(args)
... print 'Effective arg was: %s' % `x`
...
>>> foo('one arg')
We know we have one non-default arg: 'one arg'
Effective arg was: 'one arg'
>>> foo(None)
We know we have one non-default arg: None
Effective arg was: None
>>> foo()
We can supply a default arg, even None
Effective arg was: None
>>> foo(None,'too many')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 8, in foo
TypeError: foo() takes 0 or 1 arguments (2 given)
Hm. It occurs to me that *args also lets you put defaults at the front if you like,
and specify not just min and max number of args. E.g., a textout method could
use current x,y by default or allow override (obviously this example is just
about parameter passing, not graphics output. And no prizes for speed ;-)
>>> class GX:
... def __init__(self, x, y): self.x, self.y = x,y
... def textout(self, *args):
... if len(args) not in (1,3):
... raise TypeError,"Use textout('string') or textout(x,y,'string') (%d args given)" % len(args)
... if len(args)==1:
... x, y, a = self.x, self.y, args[0]
... else:
... x, y, a = args
... print 'output "%s" at %s,%s' % (a, x, y)
...
>>> g=GX(123, 456)
>>> g.textout('using curr pos')
output "using curr pos" at 123,456
>>> g.textout(333, 444, 'using spec pos')
output "using spec pos" at 333,444
And accurate arg count validation can be had (ignoring types):
>>> g.textout()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 5, in textout
TypeError: Use textout('string') or textout(x,y,'string') (0 args given)
>>> g.textout(1,2)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 5, in textout
TypeError: Use textout('string') or textout(x,y,'string') (2 args given)
>>> g.textout(1,2,3,4)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 5, in textout
TypeError: Use textout('string') or textout(x,y,'string') (4 args given)
Regards,
Bengt Richter
More information about the Python-list
mailing list