【问题标题】:Python super class with 2 inheritances calling function具有 2 个继承调用函数的 Python 超类
【发布时间】:2020-10-25 13:02:04
【问题描述】:

我正在尝试使用其 websocket 包装客户端休息 api,如下所示:

class Client(RequestClient, SubscriptionClient):
    def __init__(self, api_key, secret_key):
        super().__init__(api_key=api_key, secret_key=secret_key)

    def subscribe_event(self, callback, error_handler=None):
        super().subscribe_event(callback, error_handler)

def callback(msg):
    print(msg)

def error(e):
    print(e.error_code + e.error_message)

所以当我直接调用 SubsciptionClient 并执行以下操作时:

client = SubscriptionClient(api_key=api_key, secret_key=secret_key)
client.subscribe_event(callback, error)

我没问题。

但是当我这样做时

client = Client(api_key=api_key, secret_key=secret_key)
client.subscribe_event(callback, error)

我得到错误:

AttributeError: 'Client' 对象没有属性 'websocket_request_impl'

幕后(删除初始化函数...)

class SubscriptionClient():
    def __init__(self, **kwargs):
        api_key = None
        secret_key = None
        if "api_key" in kwargs:
            api_key = kwargs["api_key"]
        if "secret_key" in kwargs:
            secret_key = kwargs["secret_key"]
        self.websocket_request_impl = WebsocketRequest(api_key)

    def subscribe_event(callback, error):
        request = self.websocket_request_impl.subscribe_event(callback, error_handler)
        self.__create_connection(request)

class RequestClient(object):
    def __init__(self, **kwargs):
        api_key = None
        secret_key = None
        if "api_key" in kwargs:
            api_key = kwargs["api_key"]
        if "secret_key" in kwargs:
            secret_key = kwargs["secret_key"]

知道初始化我的超级类时我做错了什么吗?

【问题讨论】:

  • @Nicols Rey 你能检查一下 RequestClient 的源代码吗?我怀疑它在 init 中调用 super ?

标签: python-3.x superclass


【解决方案1】:

从错误输出中,很明显RequestClient__init__() 方法没有被调用。 SubscriptionClientRequestClient 都是 object 的子类。您可以使用以下方法验证这一点:

print(issubclass(RequestClient, object))
print(issubclass(SubscriptionClient, object))

# True
# True

您正在处理所谓的cooperative multiple-inheritance。您创建的结构可视化为:

            object
             /  \
            /    \     
RequestClient    SubscriptionClient
            \    /
             \  /
            Client

要解决这个问题,需要在每个子类的__init__()方法里面调用父类的__init__()方法。

class SubscriptionClient:
    def __init__(self, **kwargs):
        super().__init__()

class RequestClient:
    def __init__(self, **kwargs):
        super().__init__(**kwargs)

class Client(RequestClient, SubscriptionClient):
    def __init__(self, api_key, secret_key):
        super().__init__(api_key=api_key, secret_key=secret_key)

因为RequestClientClient 声明中列在SubscriptionClient 之前,所以关键字参数将首先传递给RequestClient 而不是SubscriptionClient

class Client(RequestClient, SubscriptionClient):

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-26
    • 2011-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    相关资源
    最近更新 更多