首页 > 解决方案 > 如何为父属性赋值并在继承函数中使用它?

问题描述

当试图在子进程中重写和实例化不同的对象时,我无法通过继承的父函数访问它。

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为子类中的类属性分配值以便在继承的函数中使用它?

标签: pythonoop

解决方案


为属性名称添加前缀__使它们成为伪私有;它们被编译器命名为包含定义函数的类的名称,正如您在错误消息中看到的那样,在实际查找名称损坏的属性名称self.__producer的方法中使用, (分配的在孩子中将被命名,并且由于您没有调用父母的,因此从未创建)。kafka_kafka__producer__producer_oldkafka__producer__init___kafka__producer

如果您希望在继承链的其他层可以访问具有相同名称的相同变量,请不要使用私有变量;使用单个下划线_表示它不是公共的,而不调用名称修改。在这种情况下,这只是意味着(至少)在父类和子类中都更改为__producer_producer很可能你想对__topicand做同样的事情__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

推荐阅读