我正在尝试封装一个对象而不改变它的默认行为,问题是当我访问它已经构建的对象时。因此,我的想法是使用继承并使用__getattr__
,__setattr__
,__getitem__
和__setitem__
并委托给封装对象,除了我自己定义的字段。< / p>
class Request(HttpRequest):
def __init__(self, request, *args, **kwargs):
self._original_request = request
super(Request, self).__init__(*args, **kwargs)
def __getattr__(self, name):
return getattr(self._original_request, name)
def __setattr__(self, name, value):
if name == '_original_request':
super(Request, self).__setattr__(name, value)
else:
self._original_request.__setattr__(name, value)
def __getitem__(self, key):
return self._original_request[key]
def __setitem__(self, key, value):
self._original_request[key] = value
如果我传递原始物体,一切都很好。如果我不这样做,我会
host = self.META['SERVER_NAME']
KeyError: u'SERVER_NAME'
我错过了什么吗?我的班级不应该与它封装的那个完全相同吗?
Internal Server Error: /
Traceback (most recent call last):
File "c:\Python27\lib\site-packages\django\core\handlers\base.py", line 115, in get_response
response = callback(request, *callback_args, **callback_kwargs)
File "c:\Python27\lib\site-packages\django\views\generic\base.py", line 68, in view
return self.dispatch(request, *args, **kwargs)
File "C:\www\lookwanted\djutils\views.py", line 35, in dispatch
return super(View, self).dispatch(Request(request), *args, **kwargs)
File "C:\www\lookwanted\djutils\views.py", line 12, in __init__
super(Request, self).__init__(*args, **kwargs)
File "c:\Python27\lib\site-packages\django\http\request.py", line 43, in __init__
self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {}
File "C:\www\lookwanted\djutils\views.py", line 21, in __setattr__
self._original_request.__setattr__(name, value)
AttributeError: can't set attribute
Traceback (most recent call last):
File "c:\Python27\lib\wsgiref\handlers.py", line 85, in run
self.result = application(self.environ, self.start_response)
File "c:\Python27\lib\site-packages\django\contrib\staticfiles\handlers.py", line 72, in __call__
return self.application(environ, start_response)
File "c:\Python27\lib\site-packages\django\core\handlers\wsgi.py", line 255, in __call__
response = self.get_response(request)
File "c:\Python27\lib\site-packages\django\core\handlers\base.py", line 178, in get_response
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
File "c:\Python27\lib\site-packages\django\core\handlers\base.py", line 217, in handle_uncaught_exception
return debug.technical_500_response(request, *exc_info)
File "c:\Python27\lib\site-packages\django\views\debug.py", line 69, in technical_500_response
html = reporter.get_traceback_html()
File "c:\Python27\lib\site-packages\django\views\debug.py", line 298, in get_traceback_html
return t.render(c)
File "c:\Python27\lib\site-packages\django\template\base.py", line 140, in render
return self._render(context)
File "c:\Python27\lib\site-packages\django\template\base.py", line 134, in _render
return self.nodelist.render(context)
File "c:\Python27\lib\site-packages\django\template\base.py", line 830, in render
bit = self.render_node(node, context)
File "c:\Python27\lib\site-packages\django\template\debug.py", line 74, in render_node
return node.render(context)
File "c:\Python27\lib\site-packages\django\template\defaulttags.py", line 284, in render
return nodelist.render(context)
File "c:\Python27\lib\site-packages\django\template\base.py", line 830, in render
bit = self.render_node(node, context)
File "c:\Python27\lib\site-packages\django\template\debug.py", line 74, in render_node
return node.render(context)
File "c:\Python27\lib\site-packages\django\template\debug.py", line 84, in render
output = self.filter_expression.resolve(context)
File "c:\Python27\lib\site-packages\django\template\base.py", line 578, in resolve
obj = self.var.resolve(context)
File "c:\Python27\lib\site-packages\django\template\base.py", line 728, in resolve
value = self._resolve_lookup(context)
File "c:\Python27\lib\site-packages\django\template\base.py", line 779, in _resolve_lookup
current = current()
File "c:\Python27\lib\site-packages\django\http\request.py", line 112, in build_absolute_uri
self.get_host(), self.path)
File "c:\Python27\lib\site-packages\django\http\request.py", line 62, in get_host
host = self.META['SERVER_NAME']
KeyError: u'SERVER_NAME'
答案 0 :(得分:2)
问题出在以下几行:
super(Request, self).__init__(*args, **kwargs)
这将导致在__init__
实例上调用HttpRequest
类的Request
方法,这是没有意义的。因此,只需摆脱那条线。
另外,我不明白为什么你首先要进行子类化。由于python有鸭子打字,并且你完全包裹了内部对象,为什么不选择:
class Request(object):
def __init__(self, request, *args, **kwargs):
self._original_request = request
def __getattr__(self, name):
return getattr(self._original_request, name)
def __setattr__(self, name, value):
if name == '_original_request':
super(Request, self).__setattr__(name, value)
else:
self._original_request.__setattr__(name, value)
def __getitem__(self, key):
return self._original_request[key]
def __setitem__(self, key, value):
self._original_request[key] = value
答案 1 :(得分:0)
堆栈跟踪显示问题:代码正在尝试在self._original_request
而不是self.__dict__
上设置属性。