#python #class #oop #inheritance
#python #класс #ооп #наследование
Вопрос:
Итак, у меня есть Base
класс с двумя дочерними классами. Идея заключалась в том, что у меня была бы модель, содержащая все данные, которые я мог бы подключить к одному из дочерних классов. Затем вызовите метод для установки заголовков для каждого из дочерних классов, а затем продублируйте данные из Model
экземпляра Child
класса. Однако я обнаружил, что после вызова add_header
метода в первом экземпляре класса (в данном случае a) b также получил заголовок. Что меня немного смутило, потому что я думал, что инициированные классы не влияют друг на друга. Мой вопрос в том, почему это так, и можно ли этого избежать?
class Base(object):
__model__ = None
headers = ['base_header','base_header2']
def add_header(self, *args):
for h in args:
self.headers.append(h)
def set_header_values(self):
for h in self.headers:
setattr(self, h, getattr(self.__model__, h))
class ChildOne(Base):
def __init__(self, model):
self.__model__ = model
class ChildTwo(Base):
def __init__(self, model):
self.__model__ = model
class Model(object):
foo = 'bar'
m = Model()
a = ChildOne(m)
b = ChildTwo(m)
a.add_header('tralala')
print b.headers // Output ['base_header','base_header2','tralala']
Комментарии:
1. Немного неясно, что вы пытаетесь сделать, почему
headers
в первую очередь не является переменной экземпляра?2. Заголовки @timgeb содержат некоторый «базовый» заголовок, который присутствует в обеих моделях
Ответ №1:
«после вызова метода add_header для первого экземпляра класса (в данном случае a) b также получил заголовок», потому что оба экземпляра имеют одинаковые заголовки переменных. заголовки должны быть экземпляром, а не переменной класса
class Base(object):
__model__ = None
def __init__(self):
self.headers = []
def add_header(self, *args):
for h in args:
self.headers.append(h)
def set_header_values(self):
for h in self.headers:
setattr(self, h, getattr(self.__model__, h))
class ChildOne(Base):
def __init__(self, model):
super(ChildOne, self).__init__()
self.__model__ = model
class ChildTwo(Base):
def __init__(self, model):
super(ChildTwo, self).__init__()
self.__model__ = model
class Model(object):
foo = 'bar'
m = Model()
a = ChildOne(m)
b = ChildTwo(m)
a.add_header('tralala')
print a.headers
print b.headers
Вывод
[‘tralala’]
[]
Дополнительное примечание
Переменные класса и экземпляра Python вызывают путаницу. Рассмотрим следующий пример:
class A:
l =[]
class B:
l =[]
x = A()
y = A()
x.l.append(1)
print 'class A ', A.l, x.l, y.l
x = B()
y = B()
x.l = [1]
print 'class B ', B.l, x.l, y.l
Вывод
class A [1] [1] [1]
class B [] [1] []
В обоих примерах используется очень похожий доступ к элементу данных ‘l’, однако первый пример изменяет уже существующую переменную класса, а второй пример создает новую переменную экземпляра.
В вашем примере, если бы у вас было назначение self.headers = [...]
вместо self.append(...)
вашего вывода, все было бы по-другому.
Кроме того, __model__
атрибут в вашем вопросе не имеет никакого отношения к проблеме.