Как я могу повторно использовать метод других классов без наследования в Python 2? - PullRequest
1 голос
/ 04 ноября 2019

У двух моих классов должен быть один и тот же метод, но они не связаны наследованием.

Следующие работы в Python 3:

class A(object):
    def __init__(self):
        self.x = 'A'

    def printmyx(self):
        print(self.x)

class B(object):
    def __init__(self):
        self.x = 'B'

    printmyx = A.printmyx

a = A()
b = B()

a.printmyx()
b.printmyx()

и печать

A
B

Однако в Python 2 я получаю

Traceback (most recent call last):
  File "py2test.py", line 18, in <module>
    b.printmyx()
TypeError: unbound method printmyx() must be called with A instance as first argument (got nothing instead)

Я думаю, проблема в том, что в Python 3 printmyx - это просто обычная функция, в то время как в Python 2 это несвязанный метод.

Как заставить код работать в Python 2?

edit

В моем реальном коде A и B наследуются от другого родителяклассы. Они должны использовать один вспомогательный метод, но не имеют другого отношения друг к другу.

Ответы [ 3 ]

1 голос
/ 04 ноября 2019

Имейте в виду, что Python поддерживает множественное наследование, поэтому очень возможно определить класс mixin и иметь наследование от A и B от него без нарушения основной иерархии наследования. Я понимаю, что вы говорите, что у классов мало общего - но у них есть переменная с именем x и метод для ее печати - и, по крайней мере, для меня этого достаточно, чтобы рассмотреть возможность использования наследования.

Но, тем не менее, еще один способ сделать это - использовать декоратор класса для добавления общего метода:

def add_printmyx(original_class):
    def printmyx(self):
        print (self.x)
    original_class.printmyx = printmyx
    return original_class

@add_printmyx
class B(object):
    def __init__(self):
        self.x = 'B'

b = B()
b.printmyx()

Декоратор класса берет исходный класс и добавляет (или заменяет) printmyxметод, который печатает содержимое х.

0 голосов
/ 04 ноября 2019

Очевидно, что в Python 2 исходная функция, из которой был создан несвязанный метод, хранится в атрибуте im_func. 1

Чтобы заставить код работать в Python 2 так, как он это делаетв Python 3 используйте

printmyx = A.printmyx.im_func

в теле B.

1 Описано в разделе Стандартная иерархия типов разделадокументация модели данных Python 2.

0 голосов
/ 04 ноября 2019

Почему наследование не разрешено? Это идеальный вариант использования для наследования.

class Common(object):
    def printmyx(self):
        print(self.x)

class A(Common):
    def __init__(self):
        self.x = 'A'

class B(Common):
    def __init__(self):
        self.x = 'B'

a = A()
b = B()

a.printmyx()
b.printmyx()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...