Python 多个 类 继承错误。我怎样才能正确初始化它们?

Python multiple classes inheritance error. How can I initialize them correctly?

我正在尝试为我编写的 HTTP RESTful API 构建一个 python3 模块。

我的想法是创建一个 base class,它应该有一个 request.Session() 属性,这样我就可以为它分配一个授权令牌 header,不用担心关于它还有记录器功能等等。 问题是一个名为 User 的 class 继承自 2 classes:PublicUserbase 我无法正确初始化它们。

这是我第一次使用继承 class 所以显然我遗漏了一些东西。

这是我的文件夹结构:

examplemodule/
  |--> __init__.py
  |--> classes/
        |-->  base.py
        |-->  user.py

base.py

from requests import Session
from requests.sessions import session


class Logger:
    def __init__(self):
        pass

    def log(self, message):
        print(message)


class Base:
    def __init__(self, token=None):
        if not hasattr(self, 'logger'):
            self.logger = Logger()
        if not hasattr(self, 'session'):
            self.session = Session()
            self.session.headers.update(
                {'authorization': 'Token {}'.format(token)}
            )
            # Try to login to see if token is valid, if not raise exception
            # If token is valid then the retrieved user json is saved
            self._user = {
                'id': 1,
                'username': 'test1',
                'email': 'test@test.com'
            }

user.py

from .base import Base

PUBBLIC_USER_ATTRS = ['id', 'username']
PRIVATE_USER_ATTRS = ['email']


class PublicUser:
    def __init__(self, user):
        for k in PUBBLIC_USER_ATTRS:
            setattr(self, k, user[k])


class User(Base, PublicUser):
    def __init__(self, token=None):
        super(Base, self).__init__(token=token)
        super(PublicUser, self).__init__(self._user)
        for k in PRIVATE_USER_ATTRS:
            setattr(self, k, self._user[k])

__init__.py

from .classes.user import User

然后测试我的模块 运行:

import examplemodule
examplemodule.User(token='')

但不幸的是我在 super(Base, self).__init__(token=token)

得到了一个 TypeError

TypeError: super() takes no keyword arguments

解决这个问题的最佳方法是什么?

super 用于 cooperative 继承,其中所有涉及的 类 都在使用 super 以确保所有必要的方法都是叫。这意味着 super 应该 被基础 类 使用,即使它们继承自 object.

class Base:
    def __init__(self, *, token=None, **kwargs):
        super().__init__(**kwargs)
        if not hasattr(self, 'logger'):
            self.logger = Logger()
        if not hasattr(self, 'session'):
            self.session = Session()
            self.session.headers.update(
                {'authorization': 'Token {}'.format(token)}
            )
            # Try to login to see if token is valid, if not raise exception
            # If token is valid then the retrieved user json is saved
            self._user = {
                'id': 1,
                'username': 'test1',
                'email': 'test@test.com'
            }

class PublicUser:
    def __init__(self, *, id, username, **kwargs):
        super().__init__(**kwargs)
        self.id = id
        self.username = username
        
class User(Base, PublicUser):
    def __init__(self, *, email, **kwargs):
        super().__init__(**kwargs)
        self.email = email


u = User(token='...', id='...', username='...', email='...')

User.__init__ 只需调用一次 super().__init__,知道它的基础 类 也使用 super().__init__ 总是调用下一个 __init__,直到到达 MRO 的末尾。您从 User.__init__ 开始,它调用 Base.__init__,它调用 PublicUser.__init__ 而不是 object.__init__),它最终调用 object.__init__.

在每一步中,剩余的关键字参数都分为处理的“已知”参数和向上传递的“未知”参数。最终,所有关键字对象都应该在 object.__init__ 被调用时被提取和处理。

请参阅 https://rhettinger.wordpress.com/2011/05/26/super-considered-super/ 以更全面地解释它在实践中的工作原理(特别是,为什么关键字参数优于位置参数)。

您可能想像这样调用 super-类 的构造函数:

Base.__init__(self, token=token)
PublicUser.__init__(self, self._user)