如何为父属性赋值并在继承的函数中使用它

  • 本文关键字:函数 继承 属性 赋值 python oop
  • 更新时间 :
  • 英文 :


当试图重写和实例化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

最新更新