我正在研究Django官方文档中的以下代码
from django.http import HttpResponse
import datetime
def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
然后我深入研究django.http 的源代码
class HttpResponse(HttpResponseBase):
"""
An HTTP response class with a string as content.
This content can be read, appended to, or replaced.
"""
streaming = False
def __init__(self, content=b'', *args, **kwargs):
super().__init__(*args, **kwargs)
# Content is a bytestring. See the `content` property methods.
self.content = content
def __repr__(self):
return '<%(cls)s status_code=%(status_code)d%(content_type)s>' % {
'cls': self.__class__.__name__,
'status_code': self.status_code,
'content_type': self._content_type_for_repr,
}
def serialize(self):
"""Full HTTP message, including headers, as a bytestring."""
return self.serialize_headers() + b'rnrn' + self.content
__bytes__ = serialize
@property
def content(self):
return b''.join(self._container)
@content.setter
def content(self, value):
# Consume iterators upon assignment to allow repeated iteration.
if (
hasattr(value, '__iter__') and
not isinstance(value, (bytes, memoryview, str))
):
content = b''.join(self.make_bytes(chunk) for chunk in value)
if hasattr(value, 'close'):
try:
value.close()
except Exception:
pass
else:
content = self.make_bytes(value)
# Create a list of properly encoded bytestrings to support write().
self._container = [content]
Q1:既然content
是在def __init__(self, content=b'', *args, **kwargs):
中定义的关键字参数,我们不应该使用return HttpResponse(content=html)
吗?
Q2:装饰器@content.setter
在哪里定义?
Q3:何时&属性self._container
是在哪里定义的?
Q4:命令return HttpResponse(html)
的一切如何?
发现类似的问题Django的http.response的_container
属性是什么?,但我根本不明白答案。
Q1:python关键字参数接受ordered arguments without keyword
和unordered arguments with keyword
。关键字参数始终带有默认值。我给你举个例子。
def f(a=0,b=0,c=0):
pass
f(1,2,3)
f(a=1,b=2,c=3)
f(1,b=2,c=3)
#they call funciton f with same arguments
Q2:@content.setter
是一个属性装饰器。它与@property
一起产生效果
如果您不熟悉setter
和getter
。我给您简要介绍一下:我们可以直接给对象的属性一个值,但如果我们想做一些转换或检查,那么我们可以使用属性装饰器
这是关于属性装饰器的Python文档。你可以阅读它。
Q3:我对此不确定。也许有些人可以给出更好的答案。但我想self._container
不需要定义。_container
将由@content.setter
初始化,如果_container
在初始化之前被调用,它将抛出一个错误,这可能是作者的意图,因为你不能不返回一个不好的init HttpResponse。
Q4:如果您真的对return HttpResonse(html)
的工作方式感兴趣。我建议你使用调试模式。在visualstudio代码或pycharm或任何其他流行的IDE中运行调试模式很容易
然后你可以一步一步地运行代码。在每一步你都可以调查上下文中的每个变量。相信我,这很有帮助。我总是使用调试来研究框架。