Безопасно менять базовый класс в python?
Такие вопросы существуют, но нет точно такого, и я не нашел вполне удовлетворительных ответов.
Я делаю биологическую модель на основе агентов. Предположим, что у меня есть класс ячейки типа A и один из типов B. Они возрастают в соответствии с часами. Предположим, что когда ячейка типа A достигает определенного возраста, она изменяется на ячейку типа B.
У меня есть инвентарь ячеек. Я не хочу просто создавать новые B-ячейки и добавлять их в инвентарь и оставлять ячейки A все еще в инвентаре.
Это работает, но безопасно?
class B(object):
pass
class A(object):
def changeToB(self):
self.__class__ = B
Или, есть ли лучший подход?
Ответы
Ответ 1
Хотя это может быть безопасно для переводчика, это определенно небезопасно для того, чтобы понять, что происходит.
Трудно найти более естественное сопоставление с дизайном объекта, чем биологическая ячейка, и вы пытаетесь отбросить то, что естественно там. Возраст ячейки имеет, а различные механизмы включаются и выключаются как функция возраста. В мире остеобласт не появляется и остеоцит занимает свое место, а клетка сохраняет свою "идентичность", но ведет себя по-разному в зависимости от государственных ценностей, таких как возраст.
Я бы, конечно, принимал такие соображения в объектной модели, если бы я кодировал такую модель.
Ответ 2
Я пробовал это много лет назад, работая над парсером. Казалось, что я делал то, что хотел в то время, поэтому был достаточно безопасен с точки зрения языка, но теперь я старше и мудрее, я не думаю, что буду использовать его для кода, который может кому-то еще понадобиться, - я не знаю, t думаю, что это очень "безопасно" с этой точки зрения
Ответ 3
Это может быть хорошим местом для делегирования. Внутренне вы сохраняете фактический тип объекта, который вы хотите, и выключайте его, когда это необходимо.
class B(object):
def do_something(self):
print "I'm a B"
class A(object):
def do_something(self):
print "I'm an A"
class AorB(object):
def __init__(self):
self.identity = A()
def changeToB(self):
self.identity = B()
def do_something(self):
self.identity.do_something()