Динамически привязать метод к экземпляру класса в python

Предположим, что у меня есть класс, определенный в moduleA.py которому я хочу добавить метод, используя какой-то метод загрузчика, который принимает имя второго модуля и метод, определенный там, который должен быть связан

 class ClassA(object): def __init__(self,config): super(ClassA, self).__init__() self.a = 1 self.b = 2 self.meth1 = self. bind_method(config) def bind_method(self,config): # load method <return method defined in config as a str 'moduleB.meth2'> def calling_method(): return self.meth1() 

где метод, определенный в moduleB.py выглядит примерно так:

 def meth2(self): return self.a + self.b 

Дело в том, что я хочу иметь возможность писать meth2 чтобы иметь возможность доступа к переменным класса ClassA когда он связан. Таким образом, когда у вас будет что-то вроде:

 from moduleA import ClassA A = ClassA() aout = A.calling_method() 

Вызов A.calling_method() корректно вызывает метод, определенный в moduleB.py .

Я видел такую ​​привязку, выполненную в ответах на SO после того, как ClassA с использованием types.MethodType , но я не смог types.MethodType , как связать внутри определения класса, чтобы он выполнялся внутри, когда экземпляр класса ,

Любые предложения о том, что следует использовать в методе bind_method , будут высоко оценены.

  • Составляющие функции в python
  • Почему json.dumps () необходимо в Flask?
  • Python-Flask: передавать данные в машинный скрипт python и возвращать результаты
  • Почему я не могу изменить хост и порт, на которых работает приложение Flask?
  • Как преобразовать шестнадцатеричный триплет в кортеж RGB и обратно?
  • На практике, каковы основные виды использования нового синтаксиса «выход из» в Python 3.3?
  • Python Tornado: отсутствует модуль WSGI?
  • Gunicorn Импорт по имени файла не поддерживается (модуль)
  • 4 Solutions collect form web for “Динамически привязать метод к экземпляру класса в python”

     import sys import types def getobj(astr): """ getobj('scipy.stats.stats') returns the associated module getobj('scipy.stats.stats.chisquare') returns the associated function """ try: return globals()[astr] except KeyError: try: return __import__(astr, fromlist=['']) except ImportError: modname, _, basename = astr.rpartition('.') if modname: mod = getobj(modname) return getattr(mod, basename) else: raise class ClassA(object): def __init__(self, methpath): super(ClassA, self).__init__() self.a = 1 self.b = 2 self.meth1 = types.MethodType(getobj(methpath), self) a = ClassA('moduleB.meth2') print(a.meth1()) # 3 

    Пропустив содержимое конфига, которое мне было непонятно, привязка будет выглядеть так:

     from moduleB import meth2 ClassA.meth1 = meth2 

    Важная часть заключается в том, что вы привязываетесь к классу, а не к экземпляру. Таким образом, если вы meth1 в экземпляре, он автоматически получит экземпляр в качестве первого аргумента.

    Поскольку meth2 () является функцией, это дескриптор, и вы можете связать его, вызвав метод __get __ ().

     def meth2(self): return self.a + self.b class ClassA(object): def __init__(self,config): super(ClassA, self).__init__() self.a = 1 self.b = 2 self.meth1 = config.__get__(self, ClassA) c = ClassA(meth2) print c.meth1() #correctly prints 3 

    На самом деле существует гораздо более простой способ сделать это:

     class ClassA(object): def __init__(self,config): super(ClassA, self).__init__() self.a = 1 self.b = 2 from moduleB import meth2 as meth1 def calling_method(): return self.meth1() 
    Python - лучший язык программирования в мире.