self modifying code

Robin Becker robin at NOSPAMreportlab.com
Mon May 1 17:02:07 CEST 2006


taleinat at gmail.com wrote:
> Yes, my implementation was less efficient because of the extra function
> call.
> 
>> class Weird(object):
>>         @staticmethod
>>         def __call__(arg):
>>                 data = 42
>>                 def func(arg):
>>                         return arg+data
>>                 Weird.__call__ = staticmethod(func)
>>                 return func(arg)
>> c = Weird()
> 

ugh indeed

> Ugh... you've used a class just like a function. You can't have two
> different objects of this class, since you are overriding a static
> method of the class! And you've hard-coded the data into the class
> definition. Yes, it works, but I would never, ever trust such code to
> someone else to maintain.
> 
> And you'll have to manually define such a class for every such
> function. That's not very Pythonic.

no arguments here


> 
> Here's a reusable function that will define such a class for you, as
> well as hide most of the ugliness (in fact, it supports -exactly- the
> same interface as my previous implementation):
> 
> def InitializingFunction(func):
>     class temp:
>         @staticmethod
>         def __call__(*args, **kw):
>             temp.__call__ = staticmethod(func())
>             return temp.__call__(*args, **kw)
>     return temp()
> 
> @InitializingFunction
> def func():
>     data = somethingcomplexandcostly()
>     def foo(a): 
>         return simple(data, a) 
>     return foo
> 

I already tried this kind of factory function, but in fact I think the 
original global test version outperforms even the statically coded Weird 
class.

ie
data = None
def d(arg):
	global data
	if data is None:
		data = 42
	return arg+data

@InitializingFunction
def e():
	data = 43
	def foo(a):
		return data+a
	return foo

are both better than any except the global function replacement nonsense

C:\Tmp>\Python\lib\timeit.py -s"from dingo import d;d(0)" d(1)
1000000 loops, best of 3: 0.556 usec per loop

C:\Tmp>\Python\lib\timeit.py -s"from dingo import e;e(0)" e(1)
1000000 loops, best of 3: 1.09 usec per loop

but the structured approach is still twice as slow as the simplistic one :(
-- 
Robin Becker



More information about the Python-list mailing list