I'm writing a function that exponentiates an object, i.e. given a and n, returns an. Since a needs not be a built-in type, the function accepts, as a keyword argument, a function to perform multiplications. If undefined, it defaults to the objects __mul__
method, i.e. the object itself is expected to have multiplication defined. That part is sort of easy:
def bin_pow(a, n, **kwargs) :
mul = kwargs.pop('mul',None)
if mul is None :
mul = lambda x,y : x*y
The thing is that in the process of calculating an the are a lot of intermediate squarings, and there often are more efficient ways to compute them than simply multiplying the object by itself. It is easy to define another function that computes the square and pass it as another keyword argument, something like:
def bin_pow(a, n, **kwargs) :
mul = kwargs.pop('mul',None)
sqr = kwargs.pop('sqr',None)
if mul is None :
mul = lambda x,y : x*y
if sqr is None :
sqr = lambda x : mul(x,x)
The problem here comes if the function to square the object is not a standalone function, but is a method of the object being exponentiated, which would be a very reasonable thing to do. The only way of doing this I can think of is something like this:
import inspect
def bin_pow(a, n, **kwargs) :
mul = kwargs.pop('mul',None)
sqr = kwargs.pop('sqr',None)
if mul is None :
mul = lambda x,y : x*y
if sqr is None :
sqr = lambda x : mul(x,x)
elif inspect.isfunction(sqr) == False : # if not a function, it is a string
sqr = lambda x : eval('x.'+sqr+'()')
It does work, but I find it an extremely unelegant way of doing things... My mastery of OOP is limited, but if there was a way to have sqr point to the class' function, not to an instance's one, then I could get away with something like sqr = lambda x : sqr(x)
, or maybe sqr = lambda x: x.sqr()
. Can this be done? Is there any other more pythonic way?