python: изменение класса объекта при многоуровневом наследовании

#python #class #multiple-inheritance

#python #класс #множественное наследование

Вопрос:

Я просмотрел много вопросов, размещенных здесь, чтобы найти ответ на мою проблему, но мне это не удалось. Проблема может заключаться в том, что я просто не знаю, на какие ключевые слова мне следует обратить внимание. Итак, моя проблема заключается в следующем:

У меня есть программа с многоуровневым наследованием, и я пытаюсь выяснить, как наилучшим способом было бы изменить класс объекта на подкласс. Допустим, у меня есть следующий код:

 class A(object):

    def __init(self, filename, ..)
        super(A, self).__init__()
        ...some assignments here

class B(A):

    def __init(self, filename, ..)
        super(B, self).__init__()
        ...some assignments here

class C(A):

    def __init(self, filename, ..)
        super(C, self).__init__()
        ...some assignments here
  

и так далее…
Я всегда хочу начать инициализацию объекта класса A. В зависимости от типа используемого файла назначения могут отличаться, и в зависимости от этих назначений я могу определить, что это за файл. Итак, теперь я хочу изменить класс объекта на любой подходящий класс..

Я знаю, что мог бы передать объект A в B или C и использовать copy или deepcopy, но в A я назначаю объект, ссылка на который не должна меняться, и некоторые другие, где она должна измениться. Также мне нужно было бы удалить этот объект A после инициализации B или C.

 class B(A):

    def __init__(self, filename, objA = None):
        if objA is not None:
            self.__dict__ = copy.deepcopy(objA.__dict__)
            del(objA)
        else:
            super(B, self).__init__(filename)
  

Также есть другая возможность, изменив атрибут _class на другой класс и используя какой-то метод обновления нового класса.
Я хотел бы знать, какой из двух подходов рекомендуется или есть даже лучший. Заранее спасибо.

Ответ №1:

Вам нужна фабрика: функция, которая открывает файл, считывает материал, который ему нужно прочитать, чтобы выяснить, что это за файл, а затем инициализирует и возвращает объект соответствующего класса.

Если вы хотите сохранить его как класс, вам нужно переопределить __new__() , а затем вернуть объект нужного класса вместо его собственного класса. (Вы также можете сделать это с помощью метакласса и переопределить __call__() его.)

Вы также можете изменить класс экземпляра после его создания, изменив его __class__ атрибут, чтобы указать на нужный класс. Это сработает, но factory будет более знаком другим программистам, которые будут читать ваш код.

Комментарии:

1. Спасибо за ваш ответ, там есть кое-что интересное. Проблема в том, что я не могу читать все в начале, потому что некоторые методы, которые я использую в классах, будут давать ложную информацию, если это не тот файл, который он должен быть. Я забыл упомянуть об этом раньше.

Ответ №2:

Этот код объяснит, что вы хотите сделать

 class B(object):
    def x(self):
        print 'b'

class A(object):
    def x(self):
        print 'a'
  

Теперь мы создаем два объекта

 a = a()
b = b()

a.x()
a

b.x()
b
  

теперь, если вы хотите, чтобы ‘a’ стал объектом B

  a.__class__ = type(b)
  

или

  a.__class__ = B
  

теперь атрибут x принадлежит классу B.

  a.x()
 b
  

Комментарии:

1. Да, как я упоминал в последнем разделе моего поста, я знаю об этом методе, но все равно спасибо.