self modifying code
Robin Becker
robin at NOSPAMreportlab.com
Mon May 1 05:44:03 EDT 2006
taleinat at gmail.com wrote:
........
>
> What have we gained from this? Two major advantages:
> * no ugly 'global' statement
> * no reliance on the function's name
I don't dispute either of the above, however, the actual overhead of
your approach appears to be much higher (see below) probably because it
has two function calls instead on one to get the answer.
>
> And now you can easily create such functions forever using this class
> to abstract away the ugly implementation ;)
....... yes indeed
######file dingo.py
class InitializingFunction(object):
def __init__(self, init):
def initializer(*args, **kw):
self.func = init()
return self(*args, **kw)
self.func = initializer
def __call__(self, *args, **kw):
return self.func(*args, **kw)
def init():
data = 42
def foo(arg):
return arg+data
return foo
a = InitializingFunction(init)
def b(arg):
global b
data = 42
def b(arg):
return arg+data
return b(arg)
######
Testing with timeit
C:\Tmp>\Python\lib\timeit.py -s"from dingo import a;a(0)" a(1)
100000 loops, best of 3: 2.25 usec per loop
C:\Tmp>\Python\lib\timeit.py -s"from dingo import b;b(0)" b(1)
1000000 loops, best of 3: 0.52 usec per loop
so since the simple function is fairly trivial the overhead seems to be
around 4 times that of the weird approach.
The global naming stuff is pretty flaky and relies on the way names are
looked up; in particular it seems as though references to the original
global will be held at least throughout a single statement. If the first
call is "print b(0),b(1)" then b is initialised twice.
This 'masterpiece of obfuscation' ;) gets round that problem, but is
pretty odd to say the least and still relies on knowing the class name.
class Weird(object):
@staticmethod
def __call__(arg):
data = 42
def func(arg):
return arg+data
Weird.__call__ = staticmethod(func)
return func(arg)
c = Weird()
it is still more expensive than b, but not by much
C:\Tmp>\Python\lib\timeit.py -s"from dingo import c;c(1)" c(1)
1000000 loops, best of 3: 0.709 usec per loop
--
Robin Becker
More information about the Python-list
mailing list