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:PublicUser
和 base
我无法正确初始化它们。
这是我第一次使用继承 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)
我正在尝试为我编写的 HTTP RESTful API 构建一个 python3 模块。
我的想法是创建一个 base
class,它应该有一个 request.Session()
属性,这样我就可以为它分配一个授权令牌 header,不用担心关于它还有记录器功能等等。
问题是一个名为 User
的 class 继承自 2 classes:PublicUser
和 base
我无法正确初始化它们。
这是我第一次使用继承 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)