3

我想知道一个模块在 Python 中是如何真正工作的。例如我有这个代码

import requests
r = requests.get("http://www.google.com")
print r.status_code

现在根据我的理解,请求模块应该有一个python文件,其中包含一个名为“get”的类,并且在“get”类中必须有一个名为“status_code”的成员变量所以当我创建对象“r” ,我得到它的变量 status_code 。

但是,当我查看包中的所有文件时,我找不到任何名为“get”的类。然而,我可以在一个名为“response”的类下找到一个名为“get”的函数。但是由于我们没有将对象创建为“response”类的实例,我们如何访问其中的“get”函数呢?

我想我在这里遗漏了一个关键概念,有人可以为我指出吗?

谢谢

4

2 回答 2

4

当你的import requests文件__init__.py被执行时,如果你在你的案例中检查那个文件,你会发现这一行:

from .api import request, get, head, post, patch, put, delete, options

这意味着api.py您正在导入get()功能:

def get(url, **kwargs):
    kwargs.setdefault('allow_redirects', True)
    return request('get', url, **kwargs)

如您所见,它调用请求函数api.py,如下所示:

def request(method, url, **kwargs):
    session = sessions.Session()
    return session.request(method=method, url=url, **kwargs)

这将创建一个Session在内部定义的对象session.py,然后调用它的方法request。此方法将调用方法,该方法send()返回一个在内部Response类中定义的对象(我复制第一行):Responsemodels.py

class Response(object):
    def __init__(self):
        super(Response, self).__init__()

        self._content = False
        self._content_consumed = False

        #: Integer Code of responded HTTP Status.
        self.status_code = None
...

这是status_code定义的位置,因此当您调用时,r = requests.get("http://www.google.com")您正在检索此对象,然后您可以访问status_code

于 2013-08-07T10:41:46.007 回答
2

你的理解并不完全正确。

requests模块是一个对象;.get然后是对该对象的属性查找;它必须是可调用对象,因为您尝试使用(...)语法调用它。这意味着它可以是一个类、一个函数或任何其他具有__call__方法的对象。

那个可调用的返回一些东西;所有可调用对象都可以。对于一个类,通常会返回一个实例,但对于一个可以是任何Python 对象的函数。无论做什么.get(),它都会返回一个具有.status_code属性的对象,或者具有.__getattr__在使用 name 调用时返回某些内容的方法status_code

在这种特定情况下,get()是一个函数,它已被导入到requests/__init__.py包初始化模块中。此函数间接创建一个Session()实例,并调用该实例上的.request()方法。该方法最终返回一个Response实例,它确实有一个.status_code属性

于 2013-08-07T10:31:53.730 回答