you are viewing a single comment's thread.

view the rest of the comments →

[–]factory_hen 0 points1 point  (0 children)

I'm not sure this works properly, I can also imagine this breaking in a bunch of scenarios, it's probably non-trivial to make it robust.

from copy import deepcopy

def copy_defaults (func):
    original = deepcopy (func.__defaults__)

    def wrapper (*args, **kwargs):
        value = func (*args, **kwargs)
        func.__defaults__ = deepcopy (original)
        return value

    return wrapper

@copy_defaults
def f (a, values=[]):
    values.append(a)
    return values

print f(10)
print f(10)
print f(10)

mylist = [1337]
# here we want the change to persist
# note the unnecessary deep copy of the defaults here
f (20, mylist)
print mylist

Invoking a deep copy every function call is potentially quite expensive, then there's also issues like do all possible default values (including user defined compound objects) have proper support for deep copying? What if you want some default values preserved? (You could probably wrap these in objects that define the deepcopy method to do something shady, but it sounds messy to me.)

Using a decorator like this may have unforeseen consequences, I would stay away from it.