【问题标题】:Passing kwargs to parent class from inheritance relationship in child class从子类中的继承关系将kwargs传递给父类
【发布时间】:2020-04-06 18:44:42
【问题描述】:

我有一个父类 RestResponse 和子类 AccessDeniedResponse 的继承关系如下:

class RestResponse():
    def __init__(self, data=None, content_type=None, message=None, count=None, data_status=True, **kwargs):

        data_content = {
            'status': data_status,
            'message': message,
            'data': data,
        }
        if count:
            data_content.update({
                'count': count
        })
        super(RestResponse, self).__init__(
            data=data_content,
            content_type=content_type,
            **kwargs
        )


class AccessDeniedResponse(RestResponse):
    status_code = 401

当我调用 AccessDeniedResponse(errorMessage= '您无权下载。') 它会给出这个错误:

Traceback (most recent call last):
  File "/home/ram/goenv/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
     response = get_response(request)
  File "/home/ram/goenv/lib/python3.7/site-packages/django/core/handlers/base.py", line 115, in _get_response
     response = self.process_exception_by_middleware(e, request)
  File "/home/ram/goenv/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/ram/goenv/lib/python3.7/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/ram/goenv/lib/python3.7/site-packages/django/views/generic/base.py", line 71, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/ram/goenv/lib/python3.7/site-packages/rest_framework/views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "/home/ram/goenv/lib/python3.7/site-packages/rest_framework/views.py", line 462, in handle_exception
   response = exception_handler(exc, context)
  File "/home/ram/gomech/crapp/crapp/handlers/exception.py", line 10, in cr_exception_handler
   raise exc
  File "/home/ram/goenv/lib/python3.7/site-packages/rest_framework/views.py", line 502, in dispatch
   response = handler(request, *args, **kwargs)
  File "/home/ram/gomech/crapp/crapp/rest_api_views/orders.py", line 439, in get
   return AccessDeniedResponse(errorMessage= 'You are not authorised to download.')
  File "/home/ram/gomech/crapp/crapp/responses.py", line 20, in __init__
  **kwargs
TypeError: __init__() got an unexpected keyword argument 'errorMessage'

【问题讨论】:

  • 是的,errorMessage 没有在任何地方定义为有效参数,Response.__init__ 最终“拒绝”它。你的意思是message 吗?
  • @deceze 但是有 **kwargs 所以所有的 kwargs 都应该被接受。
  • 但超类不接受它,请参阅here,我假设第 20 行是您对super().__init__() 的调用中的**kwargs
  • 即使您将Response 作为父类删除,问题仍然存在。现在您将 errorMessage 作为 kwarg 传递给 object,它也不知道如何处理它。
  • 不从Response继承可能不是一个好主意。只需 pop 任何父类不期望的 kwargs(并在调用 super() 后对它们进行处理)。

标签: django python-3.x django-rest-framework


【解决方案1】:

AccessDeniedResponse 没有自己的__init__,因此继承了RestResponse 的。
RestResponse.__init__ 接受参数为kwargs,然后将其传递给 家长:

super(RestResponse, self).__init__(
    data=data_content,
    content_type=content_type,
    **kwargs
)

这里它的父级是object(*在你有minimised the example之后...),所以这个问题可以简洁地重现:

>>> object(errorMessage='foo')
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: object() takes no arguments

换句话说,通过传递参数可以正常工作。继承链中没有任何东西可以接受特定的关键字参数。

【讨论】:

  • OP 实际上不是从object 继承的,所以super() 会引发另一个错误,说没有超类。
  • 隐式从对象继承。此处的确切错误消息为TypeError: object.__init__() takes exactly one argument (the instance to initialize)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-03-18
  • 2012-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多