Python 3 继承AttributeError。如何解决?
Python 3 inheritance AttributeError. How to solve it?
我已经阅读了很多关于 Python 继承的内容,但我不明白如何以正确的方式使用它。我使用 Java 了解了继承的工作原理,所以我想这就是我有点困惑的原因。
这是我的超级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
如你所见,我有一个很大的init,我想在我的subclass中继承它。我还有一个抽象方法要在 subclass.
中实现
这是我的子代码class:
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))
如我所料,我得到一个 AttributeError
AttributeError: 'AttackDB' object has no attribute '_AttackDB__coll'
我的问题是,有什么办法可以不重写这个洞init?
谢谢。
编辑:
在超级 class 中返回 self.__db
和 self.__coll
怎么样?它对我有用,但我不确定它是否是 "good" 解决方案。
欢迎来到 Python,埃琳娜!
正如您已经注意到的,Python 在处理继承方面与其他语言略有不同。由于 python 的性质,您找到的内容称为 name mangling
。
所以如果你写:
class MongoData:
def __init__(self, db_name, coll_name):
self.__config = configparser.ConfigParser()
你在 child 中得到的是名为 _MongoData__config
的变量,而不是 self.__config
(还记得那里的 _AttackDB__coll
吗?)这可能会让你有点困惑,但是当你更好地理解如何 Python 工作终于开始有意义了。
一种语言的最佳实践并不总是适用于其他语言,因此这里的建议是使用不同的命名或使用组合而不是继承。即使 Mixin 模式在某种程度上也可能是危险的。
希望这能回答您的问题。
我已经阅读了很多关于 Python 继承的内容,但我不明白如何以正确的方式使用它。我使用 Java 了解了继承的工作原理,所以我想这就是我有点困惑的原因。
这是我的超级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
如你所见,我有一个很大的init,我想在我的subclass中继承它。我还有一个抽象方法要在 subclass.
中实现这是我的子代码class:
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))
如我所料,我得到一个 AttributeError
AttributeError: 'AttackDB' object has no attribute '_AttackDB__coll'
我的问题是,有什么办法可以不重写这个洞init?
谢谢。
编辑:
在超级 class 中返回 self.__db
和 self.__coll
怎么样?它对我有用,但我不确定它是否是 "good" 解决方案。
欢迎来到 Python,埃琳娜!
正如您已经注意到的,Python 在处理继承方面与其他语言略有不同。由于 python 的性质,您找到的内容称为 name mangling
。
所以如果你写:
class MongoData:
def __init__(self, db_name, coll_name):
self.__config = configparser.ConfigParser()
你在 child 中得到的是名为 _MongoData__config
的变量,而不是 self.__config
(还记得那里的 _AttackDB__coll
吗?)这可能会让你有点困惑,但是当你更好地理解如何 Python 工作终于开始有意义了。
一种语言的最佳实践并不总是适用于其他语言,因此这里的建议是使用不同的命名或使用组合而不是继承。即使 Mixin 模式在某种程度上也可能是危险的。
希望这能回答您的问题。