Я пишу функцию, которая возводит в степень объект, то есть, учитывая a и n, возвращает n . Поскольку тип не должен быть встроенным, функция принимает в качестве ключевого аргумента функцию для выполнения умножений. Если значение не определено, по умолчанию используется метод objects __mul__
, т. Е. Предполагается, что для самого объекта определено умножение. Эта часть довольно проста:
def bin_pow(a, n, **kwargs) :
mul = kwargs.pop('mul',None)
if mul is None :
mul = lambda x,y : x*y
Дело в том, что в процессе вычисления n существует много промежуточных кварталов, и часто есть более эффективные способы их вычисления, чем просто умножение объекта на себя. Легко определить другую функцию, которая вычисляет квадрат и передает его в качестве другого ключевого аргумента, например:
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)
Проблема здесь возникает, если функция возведения в квадрат объекта не является автономной функцией, а представляет собой метод возведения в степень объекта, что было бы очень разумно сделать. Единственный способ сделать это, что я могу придумать, это что-то вроде этого:
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+'()')
Это работает, но я считаю, что это крайне нелегкий способ делать вещи ... Мое владение ООП ограничено, но если бы был способ заставить sqr указывать на функцию класса, а не на функцию экземпляра, тогда я мог бы получить что-то вроде sqr = lambda x : sqr(x)
или, может быть sqr = lambda x: x.sqr()
Можно ли это сделать? Есть ли какой-нибудь другой более питонический способ?