0

答案

(1)对象( )
read()方法调用其属性的方法。也就是说,是它自己的类的一个对象,并且有它自己的方法。(2)对象 的方法和文件对象的方法不一定相同。因此,他们可能会采取不同的论点。(3)必须由子类设置。(3) 是的。更准确地说,装饰器意味着每当我们引用 名称时都会调用该方法,例如. /感谢 Daniel Roseman 的回答。/问题HttpRequestselfread()_stream_streamread()


read()HttpRequest_stream
read()


self._stream


@property
self.body





我正在浏览HttpRequestDjango 类的代码。

根据下面的代码,self.body()尝试调用self.read()并将其返回值分配给self._body.
如果没有异常,它会在 self._body 上调用 StringIO 并将其返回值分配给 self._stream。

我有四个相关的问题:
(1)
是否self.read()调用自身self._stream?还是它调用文件对象的读取方法?

(2)
在 的定义中包含 args 和 kwargs 的原因是self.read什么?

(3)
对于我在 HttpRequest 的定义中发现的,self._stream是由self.body方法创建的。第一次调用
时会发生什么?self.body()估计self._stream还没有创建。
要创建它,self.body()需要先创建self._body.
要创建 self._body,调用 self.read()。
但是 s elf.read() calls .read() on self._stream
那么,它从哪里获得 self._stream 呢?

(4)
不管self.body是一个属性,还是调用self.body()方法,
它的返回值就是我们调用self.body时得到的。我对吗?

django.http.HttpRequest

class HttpRequest(object):

    #...

    def __init__(self):
        self.GET, self.POST, self.COOKIES, self.META, self.FILES = {}, {}, {}, {}, {}
        self.path = ''
        self.path_info = ''
        self.method = None
        self._post_parse_error = False

    #...

    @property
    def body(self):
        if not hasattr(self, '_body'):
            if self._read_started:
                raise Exception("You cannot access body after reading from request's data stream")
            try:
                self._body = self.read()
            except IOError, e:
                raise UnreadablePostError, e, sys.exc_traceback
            self._stream = StringIO(self._body)
        return self._body

    #...

    def read(self, *args, **kwargs):
        self._read_started = True
        return self._stream.read(*args, **kwargs)

    #...
4

1 回答 1

0
  1. 不,它调用read()任何对象的方法self._stream

  2. 这是允许将任意参数(位置和关键字)传递给方法的正常模式。在这种情况下,它们直接传递给流的 read 方法。

  3. 该代码上方的注释解释了发生了什么 - self._stream 必须由子类设置。

  4. 是的。@property装饰器意味着当您简单地引用名称时调用该方法,即 as而self.body不是self.body().

于 2013-02-26T19:50:24.760 回答