I've been reading a lot about Python inheritance, but I can't understand how to use it in the right way. I learnt about how inheritance works using Java, so I guess that's why I'm a little confused.
Here is my super class:
class MongoData:
def __init__(self, db_name, coll_name):
self.__config = configparser.ConfigParser()
self.__config.read('conf.ini')
self.__connect = self.__config.get('mongo', 'connect')
self.__client = MongoClient(self.__connect)
self.__db_name = db_name
self.__coll_name = coll_name
self.__db = None
self.__coll = None
if self.__db_name in self.__client.database_names(): # If DB already exists
print('DB exist')
self.__db = self.__client[self.__db_name]
if self.__coll_name in self.__db.collection_names(): # If collection already exists
print('Collection exists')
self.__coll = self.__db[self.__coll_name]
else: # If collection does not exist, create it
self.__db = self.__db_name
self.__coll = self.__db[self.__coll_name]
print(self.__db.collection_names())
else: # If DB does not exist, create it
print('Creating database...')
self.__db = self.__client[self.__db_name]
self.__coll = self.__db[self.__coll_name]
#print(self.__db.collection_names())
print("Database {} and collection {} successfully created.".format(self.__db_name, self.__coll_name))
def writeDB(self, wdict):
"""Method to implement"""
raise NotImplementedError
As you can see, I have a big init and I would like to inherit it in my subclass. Also I have a abstract method to be implemented in the subclass.
And here is the code of my subclass:
class AttackDB(MongoData):
__metaclass__ = abc.ABCMeta
def __init__(self, db_name, coll_name):
MongoData.__init__(self, db_name, coll_name)
@abc.abstractmethod
def writeDB(self, wdict):
doc_id = self.__coll.insert_one(attack).inserted_id
print("Attack with id {} was inserted in the DB.".format(dic_id))
As I supposed, I get a AttributeError
AttributeError: 'AttackDB' object has no attribute '_AttackDB__coll'
My question is, what can I do no to rewrite the hole init?
Thank you.
Edit:
How about in the super class returning self.__db
and self.__coll
? It works for me, but I'm not sure if it is a "good" solution.
Welcome to Python, Elena!
As you have noticed already, Python is a bit different on handling inheritance than other languages. What you found is called a name mangling
because of the nature of python.
So if you write:
class MongoData:
def __init__(self, db_name, coll_name):
self.__config = configparser.ConfigParser()
What you get in child is variable called _MongoData__config
, not the self.__config
(remember _AttackDB__coll
there? ) which might confuse you a bit, however as you understand better how Python works things finally starting to make sense.
Best practices for one language does not always work for others, so advice here is either use a different naming or use a composition over inheritance. Even Mixin pattern might be dangerous to some degree.
Hope that answers your question.