On 9 October 2011 13:20, Tim Chase <python.l...@tim.thechases.com> wrote: > My intent is to have a function object something like > > def foo(arg1, arg2=foo.DEFAULT): > return int(do_stuff(arg1, arg2)) > foo.SPECIAL = 42 > foo.MONKEY = 31415 > foo.DEFAULT = foo.SPECIAL > > so I can call it with either > > result = foo(myarg) > > or > > result = foo(myarg, foo.SPECIAL) > > However I can't do this because foo.DEFAULT isn't defined at the time the > function is created. I'd like to avoid hard-coding things while staying > DRY, so I don't like > > def foo(arg1, arg2=42) > > because the default might change due to business rule changes, I have a > dangling "magic constant" and if the value of SPECIAL changes, I have to > catch that it should be changed in two places. > > My current hack/abuse is to use __new__ in a class that can contain the > information: > > class foo(object): > SPECIAL = 42 > MONKEY = 31415 > DEFAULT = SPECIAL > def __new__(cls, arg1, arg2=DEFAULT): > return int(do_stuff(arg1, arg2)) > > i1 = foo("spatula") > i2 = foo("tapioca", foo.MONKEY) > > 1) is this "icky" (a term of art ;-) > 2) or is this reasonable > 3) or is there a better way to do what I want? >
Why do you want these argument values to be attributes of the function? Anyway, simpler than abusing classes: foo_default = 42 def foo(arg1, arg2=foo_default): ... foo.DEFAULT = foo_default del foo_default ... Or get the default at function runtime: def foo(arg1, arg2=None): if arg2 is None: arg2 = foo.DEFAULT ... foo.DEFAULT = 42 ... But I'd probably simply go for foo_DEFAULT, foo_MONKEY and foo_SPECIAL. They're also quicker (1 dict lookup instead of 2) -- Arnaud -- http://mail.python.org/mailman/listinfo/python-list