Как связать существующий метод экземпляра в одном классе с другим классом?
Я пытаюсь сделать ограниченную форму динамического mixin на классе, используя методы из стороннего класса библиотеки и привязывая их к моему классу. Но ничто из того, что я пробовал, не сработало правильно. Все примеры, которые я видел в других местах, связывают несвязанную функцию с классом, но в моем случае мне нужно привязать уже связанный метод к другому классу.
Пример кода, с которым я работал, с моими неудачными попытками:
import types import traceback class Class1(object): output = 'class1' def method(self): print self.output class Class2(object): output = 'class2' try: Class2.method = types.MethodType( Class1.method, None, Class2 ) class2 = Class2() class2.method() except: traceback.print_exc() # TypeError: unbound method method() must be called with Class1 instance as first argument (got Class2 instance instead) try: class1 = Class1() class2 = Class2() class2.method = types.MethodType( class1.method, class2, Class2 ) class2.method() except: traceback.print_exc() # TypeError: method() takes exactly 1 argument (2 given) class1 = Class1() class2 = Class2() class2.method = class1.method.__get__( class2, Class2 ) class2.method() # outputs 'class1' not 'class2'
Это возможно? Я делаю что-то неправильно? Есть ли еще одна техника, которую я не видел?
- (Udacity + GAE) Создание формы для редактирования существующих объектов ndb
- Вызовите другую функцию и, возможно, сохраните аргументы по умолчанию
- Как разбить файл на python?
- Преобразование строковых массивов в числа
- Мутирование переменной цикла во время итерации
Добавьте его в качестве родительского класса динамически, изменив значение YourClass.__bases__
:
>>> class Base: pass >>> class Foo(Base): pass >>> class Bar(Base): attr = True >>> Foo.__bases__ = (Bar,) + Foo.__bases__ >>> Foo.attr True
В качестве альтернативы можно получить объект связанного метода и извлечь исходную функцию, а затем прикрепить его как атрибут исходного класса:
YourClass.method = OtherClass.bound_method.im_func
EDIT: вы изменяете __bases__
not __mro__
. К сожалению.
Некоторая модификация в вашем коде, надеюсь, что это сработает.
import types class Class1(object): output = 'class1' def method(self): print self.output class Class2(object): output = 'class2' # you have to use im_func - bound or even unbound methods will fail class1Method = Class1().method.im_func Class2.method = types.MethodType(class1Method, Class2(), Class2) Class2().method() # it will print 'class2'
Рассматривали ли вы создание метакласса, позволяющего динамически назначать родительские классы, переопределяя mro()
таким образом, чтобы вы могли называть его позже в процессе выполнения?
В ответ на ваш недавний комментарий: возможно, вы можете использовать заводскую функцию для создания классов, которые желательны после начала модульных тестов. Это может хорошо работать с идеей использования метакласса.
- Изменение потока программы на основе доступных библиотек
- Как я могу измерить ширину рендеринга строки через tkFont, не создавая сначала окно?
- Могу ли я эффективно обменивать два экземпляра класса путем замены __dict__?
- Класс () vs self .__ class __ () при создании объекта?
- Python: как сравнить два списка словарей
- Различные размеры дикта и внутреннего объекта __dict__
- Per-class @property decorator в Python
- Selenium – общий доступ к сеансу браузера (файлы cookie, локальное хранилище) между компьютерами
- Мой логический вывод не выводит?
- Python: сделайте видео, используя несколько изображений .png
- Как получить имя модуля определения класса объекта, а не имя модуля для объекта Instantiation?