mutable default parameter problem [Prothon]

Hung Jung Lu hungjunglu at yahoo.com
Fri Jun 18 12:09:13 EDT 2004


Rob Williscroft <rtw at freenet.co.uk> wrote:
> 
> But python has static variables.
> 
> def another( x ):
>   y = getattr( another, 'static', 10 )
>   another.static = x
>   return y
> 
> print another(1), another(2), another(4)

What about the following case:

def f():
    f.static = getattr(f, 'static', 0)
    f.static += 1
    return f.static

print f(), f(), f() # prints 1 2 3

As opposed to C++, you now have a line of code that is always executed
in subsequent calls, for no good reason. This is worse than:

def f(static=[0]):
    static[0] += 1
    return static[0]

in the sense that you have a wasteful call ("getattr") that doesn't do
anything productive in subsequent calls. (You could change that to
f.static = getattr(f, 'static', 0) + 1, but the "getattr" is surely
inefficient compared to f.static += 1, and internally likely incurs
some conditional statement at some level.)

Maybe one can do instead:

def f():
    global f
    def f():
        f.static += 1
        return f.static
    f.static = 0 # initialization
    return f()
    
print f(), f(), f() # prints 1 2 3

The advantage is there is no more wasteful statements in subsequent
calls. No "if" conditional statement. The above is of course a toy
example to illustrate the case of a function that needs to perform
something special the first time it is called. (I am well aware of the
outside assignment like:

def f():
    f.static += 1
    return f.static
f.static = 0

mentioned in this thread, but I am talking about something more
general. Notice that in the latter case, f.static=0 is done before f()
is called, which may not be what one wants. E.g.: if f() is never
called, this assignment is wasteful. Not a problem in this case, for
if complicated initialization is needed, like requiring a timestamp,
it may not be a good idea.)

In code refactoring, the equivalent is to replace conditional
statements by polymorphism. In terms of codeblocks, what I mean is
dynamic hook-on and hook-off of codeblocks. If the underlying language
is powerful enough, one should be able to achieve runtime
restructuring of code, without performance impact for subsequent
calls.

regards,

Hung Jung



More information about the Python-list mailing list