returning unordered keyword arguments from a function (WAS: Are multiple return values really harmful?)

Steven Bethard steven.bethard at gmail.com
Thu Nov 18 14:52:42 EST 2004


Hung Jung Lu wrote:
> def today(p):
>     print p.message
>     r = Generic()
>     r.year, r.month, r.day = 2004, 11, 18
>     return r
> 
[snip]
> 
> I suspect a large number of people use this approach. Generic objects
> are also good for pickling/serialization. (By the way, why is the new
> style class "object()" made so that no dynamic attributes can be
> assigned to it?

My understanding is that this is for efficiency reasons...  I remember 
some older discussions, but they're kinda hard to google since 'object' 
isn't a very good query term...  Personally, I don't really care about 
being able to assign attributes dynamically to an object() instance, but 
I would like to be able to do something like:

 >>> r = object(year=2004, month=11, day=18)
 >>> r.day, r.month, r.year
(18, 11, 2004)

where object's __init__ takes keyword arguments to designate attributes. 
  This would let you use object basically as a record.  If I remember 
right though, the problem with this is that it introduces overhead for 
all classes that inherit from object.  (I kinda thought it had something 
to do with defining __slots__, but I'll wait for someone with more 
knowledge in this area to fill in the details...)


> def f():
>     if not hasattr(f,'x'):
>        f.x = 1
>     else:
>        f.x += 1
>     f.y, f.z = 2*f.x, 3*f.x
> 
> f()
> print f.x, f.y, f.z
> f()
> print f.x, f.y, f.z
> 
> Of course, this approach has more limited applicability. (Not good for
> multithreaded case, not good for renaming the function object or
> passing it around.)

Just to clarify for anyone who wasn't following closely, this is "not 
good for renaming the function object" in cases like:

 >>> def f():
...     if not hasattr(f,'x'):
...         f.x = 1
...     else:
...         f.x += 1
...     f.y, f.z = 2*f.x, 3*f.x
...
 >>> g = f
 >>> f = 2
 >>> g()
Traceback (most recent call last):
   File "<interactive input>", line 1, in ?
   File "<interactive input>", line 3, in f
AttributeError: 'int' object has no attribute 'x'

This is a little contrived here, but the point is that relying *inside* 
a function on the name that the function is def'd with is probably not a 
good idea.

Steve



More information about the Python-list mailing list