У меня возникла проблема с наследованием на python, что я знаю, как этого избежать, но не совсем понимаю. Проблема возникла при создании меню, но я разделил код только на реальную проблему. код:
class menu:
buttonlist=[]
>>> class av(menu):
def __init__(self, num):
self.buttonlist.append(num)
print self.buttonlist
>>> AV=av(12)
[12]
>>> class main(menu):
def __init__(self, num):
self.buttonlist.append(num)
print self.buttonlist
>>> Main=main(14)
[12, 14]
>>> AV.buttonlist
[12, 14]
Я бы ожидал получить [14] в ответ "Main=main (14)" и [12] с "AV.buttonlist", но вместо этого append добавил список во все классы и объекты: S может ли кто-нибудь объяснить мне, почему это?
заблаговременно!
Потому что buttonlist
- это переменная класса, а не переменная экземпляра. Вам нужно назначить его в конструкторе, если вы хотите, чтобы он был локальным для экземпляра.
class menu:
def __init__(self):
self.buttonlist = []
И тогда, конечно, не забудьте вызвать базовый конструктор в производных классах.
@Cat избил меня, но вот какой-то рабочий код
class Menu(object):
def __init__(self):
self.buttonlist = []
class AV(Menu):
def __init__(self, num):
Menu.__init__(self)
self.buttonlist.append(num)
print self.buttonlist
class Main(Menu):
def __init__(self, num):
Menu.__init__(self)
self.buttonlist.append(num)
print self.buttonlist
>>> av = AV(12)
>>> main = Main(14)
Обратите внимание, что соглашение состоит в том, чтобы назвать классы python с CamelCase, поэтому ваш класс av
будет av
и menu
будет menu
. Это отнюдь не требуется, хотя.
super(AV, self).__init__()
вместо Menu.__init__(self)
в AV.__init__
и внести соответствующие изменения в Main.__init__
(выводя это Python 2.x из-за print
скобок)
Самое простое объяснение заключается в том, что кнопочный список - это список, который изменяет и всегда будет производить этот результат. Описание Cat Plus Plus - хороший способ обойти это. Использование атрибута class вместо атрибута instance также приведет к той же проблеме.
#Main and AV.buttonlist are actually different,
print Main
print AV
#you should get something similar to this pointing to different locations
<__main__.main object at 0x02B753F>
<__main__.av object at 0x02B6B910>
#if you are using string, it different because string is immutable
class menu:
buttonlist=""
class av(menu):
def __init__(self, num):
self.buttonlist = num
class main(menu):
def __init__(self, num):
self.buttonlist = num
a=av("food")
b=main("menu")
print(menu.buttonlist)
print(a.buttonlist)
print(b.buttonlist)
##works for strings. because they are immutable.
"""in your case lists are mutable and they will generate that"""