Evil hack of the day
Neel Krishnaswami
neelk at brick.cswv.com
Wed May 26 19:19:05 EDT 1999
Well, I've found a solution to the "how do I imitate a C static
variable" question that's so gratuitously evil that it should never be
used, and should probably be forgotten immediately. Of course, I feel
like sharing. :)
The standard bad solution to the problem is something like this:
def merely_bad(n=[0]):
n[0] = n[0] + 1
return n[0]
This exploits default arguments and the mutability of lists to cause
the function to return the number of times it has been called.
However, I was looking at the attributes of a function object, and
noticed that it had an interesting-looking attribute named
func_defaults. When I looked at it it, I saw that it seemed to be a
tuple containing the functions default arguments. "Hmm," I wondered,
"I wonder if I could assign to it." And lo and behold I could!
This leads to the evil version:
>>> def evil(n=0):
... n = n + 1
... globals()['evil'].func_defaults = (n,)
... return n
...
>>> evil()
1
>>> evil()
2
>>> evil()
3
This approach misuses the default argument syntax, relies on an
implementation detail, *and* gratuitously exploits Python's
dynamism. The only way I can see to top it is to mess around with the
func_code attribute. (Now I just need to download bytecodehacks....)
Neel
More information about the Python-list
mailing list