Im a bit confused about inherited instance variables in ABCs. I have written an example to show my confusion. Class A needs a list which class B inherits but it must be an instance object rather than a class object. However class B also needs its own instance variable local. Can anyone set me straight?
#!python
from abc import ABCMeta, abstractmethod, abstractproperty
import unittest
class A(object):
__metaclass__ = ABCMeta
_internal = ['initialized']
@property
def internal(self):
return self._internal
def get_a(self):
return self._internal
@abstractmethod
def set_a(self, value):
pass
class B(A):
def __init__(self):
self.local = 'OK'
def get_local(self):
return self.local
def set_a(self, value):
self._internal.append(value)
class TestCase(unittest.TestCase):
def test_implementation(self):
self.assertEqual(['initialized'], B().get_a() ) # this passes but for wrong reason
b_used = B().set_a('used')
b_unused = B()
print "b_used.get_a() should return ['initialized','used']"
print "b_unused.get_a() should return ['initialized']"
print "b_used.get_local() should equal b_unused.get_local() = 'OK'"
self.assertEqual(['initialized'], b_unused.get_a()) # >> fails with ['initialized'] =! ['initialized', 'used']
self.assertNotEqual(b_unused.get_a(), b_used.get_a())
if __name__ == "__main__":
unittest.main()
The problem is that _internal is a class obj of class A. I need it to be an instance object of class B.
Thanks In advance
You should initialize instance attributes in
__init__()and call the base class__init__()inB:You should also fix your unit test: