__bases__ не работает! Что дальше? - PullRequest
9 голосов
/ 07 июля 2010

Следующий код не работает в Python 3.x, но раньше он работал с классами старого стиля:

class Extender:
    def extension(self):
        print("Some work...")

class Base:
    pass

Base.__bases__ += (Extender,)

Base().extension()

Вопрос прост: Какя могу динамически (во время выполнения) добавить суперкласс к классу в Python 3.x?

Но я готов, что ответ будет трудным!) * +1010 *

Ответы [ 2 ]

5 голосов
/ 08 июля 2010

Похоже, что можно динамически изменить Base.__bases__ если Base.__base__ не object. (Под динамическим изменением я подразумеваю, что все существующие ранее экземпляры, которые наследуются от Base, также динамически изменяются. В противном случае см. решение Николая Харечко ).

Если Base.__base__ - это некоторый фиктивный класс TopBase, то присвоение Base.__bases__ похоже работает:

class Extender(object):
    def extension(self):
        print("Some work...")

class TopBase(object):
    pass

class Base(TopBase):
    pass

b=Base()
print(Base.__bases__)
# (<class '__main__.TopBase'>,)

Base.__bases__ += (Extender,)
print(Base.__bases__)
# (<class '__main__.TopBase'>, <class '__main__.Extender'>)
Base().extension()
# Some work...
b.extension()
# Some work...

Base.__bases__ = (Extender, TopBase) 
print(Base.__bases__)
# (<class '__main__.Extender'>, <class '__main__.TopBase'>)
Base().extension()
# Some work...
b.extension()
# Some work...

Это было протестировано для работы в Python 2 (для классов нового и старого стиля) и для Python 3. Я понятия не имею, почему это работает, хотя это не так:

class Extender(object):
    def extension(self):
        print("Some work...")

class Base(object):
    pass

Base.__bases__ = (Extender, object)
# TypeError: __bases__ assignment: 'Extender' deallocator differs from 'object'
5 голосов
/ 07 июля 2010

Как по мне это невозможно.Но вы можете создать новый класс динамически:

class Extender(object):
    def extension(self):
        print("Some work...")

class Base(object):
    pass

Base = type('Base', (Base, Extender, object), {})
Base().extension()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...