K
K
KOS_MOS2010-10-13 12:31:42
Python
KOS_MOS, 2010-10-13 12:31:42

Explain the nuance in class inheritance in Python?

There is this code:

<font color="black"><a href="http://s-c.me/9339/s">Copy&nbsp;Source</a>&nbsp;|&nbsp;<a href="http://s-c.me/9339/h">Copy&nbsp;HTML</a><ol>
<li><font color="#008000">'''</font><br/>
<font color="#008000">Базовый&nbsp;класс</font><br/>
<font color="#008000">'''</font></li>
<li><font color="#0000ff">class</font> <font color="#cc6633">Component</font>():</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;connects = []</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#008000">'''</font><br/>
<font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;Метод&nbsp;добавляе&nbsp;объект&nbsp;в&nbsp;коллекцию</font><br/>
<font color="#008000">&nbsp;&nbsp;&nbsp;&nbsp;'''</font></li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">def</font> <font color="#cc6633">connect</font>(self, object):</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<b>self</b>.connects.append(object)</li>
<li>&nbsp;</li>
<li>&nbsp;</li>
<li><font color="#008000">'''</font><br/>
<font color="#008000">Подкласс&nbsp;1</font><br/>
<font color="#008000">'''</font></li>
<li><font color="#0000ff">class</font> <font color="#cc6633">Component1</font>(<font color="#cc6633">Component</font>):</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">def</font> <font color="#cc6633">getData</font>(self):</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">print</font> <font color="#008000">123</font></li>
<li>&nbsp;</li>
<li>&nbsp;</li>
<li><font color="#008000">'''</font><br/>
<font color="#008000">Подкласс&nbsp;2</font><br/>
<font color="#008000">'''</font></li>
<li><font color="#0000ff">class</font> <font color="#cc6633">Component2</font>(<font color="#cc6633">Component</font>):</li>
<li>&nbsp;</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">def</font> <font color="#cc6633">getData</font>(self):</li>
<li>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<font color="#0000ff">print</font> <font color="#008000">123</font></li>
<li>&nbsp;</li>
<li>&nbsp;</li>
<li>&nbsp;</li>
<li><font color="#008000">'''</font><br/>
<font color="#008000">Инстанцируем</font><br/>
<font color="#008000">'''</font></li>
<li>c1 = <font color="#cc6633">Component1</font>()</li>
<li>c2 = <font color="#cc6633">Component2</font>()</li>
<li>&nbsp;</li>
<li><font color="#008000">'''</font><br/>
<font color="#008000">Проверяем&nbsp;кол-во&nbsp;элементов&nbsp;в&nbsp;подклассе&nbsp;2</font><br/>
<font color="#008000">'''</font></li>
<li><font color="#0000ff">print</font> <b>len</b>(<font color="#cc6633">Component2</font>.connects) <font color="#696969">#&nbsp;0</font></li>
<li>&nbsp;</li>
<li><font color="#008000">'''</font><br/>
<font color="#008000">Добавляем&nbsp;первому&nbsp;подклассу&nbsp;в&nbsp;объект&nbsp;коллекцию</font><br/>
<font color="#008000">'''</font></li>
<li>c1.<font color="#cc6633">connect</font>(c2)</li>
<li>&nbsp;</li>
<li><font color="#008000">'''</font><br/>
<font color="#008000">Проверяем&nbsp;кол-во&nbsp;элементов&nbsp;в&nbsp;подклассе&nbsp;2</font><br/>
<font color="#008000">'''</font></li>
<li><font color="#0000ff">print</font> <b>len</b>(<font color="#cc6633">Component2</font>.connects) <font color="#696969">#&nbsp;1&nbsp;</font></li>
</ol></font>

Why does the number of elements in the collection of the second object change if I add an element to the collection of the first object?

Answer the question

In order to leave comments, you need to log in

3 answer(s)
S
shsmad, 2010-10-13
@shsmad

connects is an attribute of the Component class, not an instance. Inheriting classes use THIS memory address (id(c1.connects) == id(c2.connects)) If you
want it to be different, add connects = [] to the description of Component1 and Component2, as you did for the base class.

V
Vladimir Chernyshev, 2010-10-17
@VolCh

Not
connects = []
but
def __init__(self)
connects = []
PS Parser ate indents :(

M
Maxim Vasiliev, 2010-10-17
@qmax

Are you sure that you need to connect to the class, and not to the object?
then it's more correct to do it as @classmethod and not an object method.
and in order not to copy the line, the attribute can be created in the meta-class:

class MetaComp(type):
  def __init__(cls,name,bases,kwargs):
    super(MetaComp, cls).__init__(name,bases,kwargs)
    cls.connects = [] # для каждого класса и наследника будеит свой

class Comp(object):
  __metaclass__ = MetaComp

  @classmethod
  def connect(cls,obj):
    cls.connects.append(obj)

class Comp1(Comp):
  pass
    
class Comp2(Comp):
  pass

# каждый вызов добавляет к своему connects:
Comp.connect('foo')
Comp1.connect('foo1')
Comp2.connect('foo2')

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question