当试图重写和实例化child中的不同对象时,我无法通过继承的父函数访问它。
class kafka(object):
__topic = ''
__bootstrap_servers = ''
__producer : Producer
def __init__(self, *, topic: str, brokers: str, **kwargs):
self.__bootstrap_servers = brokers
self.__topic = topic
conf = {
'bootstrap.servers': self.__bootstrap_servers,
'other configs': 'config values' #<--------------
}
self.__producer = Producer(conf)
def save(self, m: message) -> bool:
r = self.__producer.produce(self.__topic, m.get())
self.__producer.flush()
return r
class oldkafka(kafka):
def __init__(self, *, topic: str, brokers: str, **kwargs):
self.__bootstrap_servers = brokers
self.__topic = topic
conf = {
'bootstrap.servers': self.__bootstrap_servers,
}
self.__producer = Producer(conf)
错误:
k = oldkafka(topic='topic',brokers='broker:9092')
k.save('message')
#r = self.__producer.produce(self.__topic, m.get())
#AttributeError: 'oldkafka' object has no attribute '_kafka__producer'
如何为子类中的类self
属性赋值,以便在继承的函数中使用它?
将属性名称与__
前缀会使它们成为伪私有的;编译器对它们进行了名称篡改,以包含在其中定义函数的类的名称,正如您在错误消息中看到的那样,在kafka
的方法中使用self.__producer
实际上查找了名称篡改的属性名称_kafka__producer
(在子对象中分配的__producer
将命名为_oldkafka__producer
,并且由于您没有调用父对象的__init__
,因此从未创建_kafka__producer
(。
如果您希望在继承链的其他层可以访问具有相同名称的同一变量,请不要使用私有变量;使用单个下划线_
表示它不是公共的,而不调用名称篡改。在这种情况下,这只意味着在父类和子类中都将(至少(__producer
更改为_producer
(假设__topic
和__bootstrap_servers
应该同时由父类和子类使用,则您可能希望对它们执行相同的操作(。
附带说明:编写不调用父类初始化器的初始化器通常是个坏主意。如果您能找到一些方法使oldkafka
尽可能多地重用kafka
的__init__
(或者全部重用,并且不在子级上实现__init__
,或者如果子级必须做更多,则用super().__init__(... args to parent go here ...)
委托给父级(,那么这将是更好的代码。例如:
class kafka(object):
__topic: str
__bootstrap_servers: str
__producer: Producer
def __init__(self, *, topic: str, brokers: str, **kwargs):
self.__bootstrap_servers = brokers
self.__topic = topic
self.__producer = self._make_producer(**kwargs)
def _make_producer(self, **kwargs):
conf = {
'bootstrap.servers': self.__bootstrap_servers,
'other configs': 'config values'
}
return Producer(conf)
# rest of class
class oldkafka(kafka):
# ... does not override __init__ at all
def _make_producer(self, **kwargs):
return Producer({'bootstrap.servers': self.__bootstrap_servers})
# rest of class