在 Python 应用程序中,找不到项目的来源

In Python application, can't find where a item comes from

我正在尝试了解 web 框架 web2py 的工作原理,但 access.py 中有一个名为 request.client 的项目我无法理解弄清楚它来自哪里。我从 here 中检索到代码,它的开头如下:

import base64
import os
import time
from gluon.admin import apath
from gluon.fileutils import read_file
from gluon.utils import web2py_uuid
from pydal.contrib import portalocker
# ###########################################################
# ## make sure administrator is on localhost or https
# ###########################################################


http_host = request.env.http_host.split(':')[0]

我的问题是:当我们不知道某个项目来自代码中的位置时,找到它的方法是什么?

当试图弄清楚一个项目是如何导入到 Python 时,您需要查看相关文件中的显式 import 语句。在编写良好的代码中,这将是显而易见的。

如果您将感兴趣的对象导入 python shell,那么您可以使用 .__file__ 属性来查找从中导入该对象的字节码文件。还有其他此类属性可能会对您有所帮助,例如

.__name__
.__path__
.__package__

如果您使用强烈推荐的 IPython,您可以通过输入 <obj>.__ 并按 Tab 键轻松获得这些双下划线方法的列表。

查看您链接的文件,我不确定 request 是从哪里导入的。但是,clientrequest 对象的一个​​属性。

您 link、access.py 的文件在第 13 行第一次提到名称 request

http_host = request.env.http_host.split(':')[0]

这个符号 request 不是从任何地方 import 编辑的。一般来说,这是编写 Python 程序的一种非正统方式,单独看来是不可能的。但是它 可能的,如果符号 request 被一些包装 access.py 执行的其他文件添加到该文件的全局工作区。这是一个最小的例子:

d = { 'request' : some_object() }
execfile( 'access.py', d )  # run the named file using d as its global workspace

因此,在这种特殊情况下,调查的方法是找到执行 access.py 的文件。

[ 回应您关于检查库中每个文件的评论:为了进行此类分析,并且通常为了提高程序员的生活质量,您 需要一些可以在整个文件层次结构中搜索特定字符串的工具(例如 Linux 和 MacOS 上的命令行工具 grep,或者 [=49 上的许多第三方文本编辑器和 IDE =],但 不是 常年不可靠的 Windows "Search" 声称能够做到这一点的函数)。 ]

在回答有关查找事物来源的更一般性问题时:其他答案和评论提到了 __file__ and/or __module__ 等属性。如果您有办法让您的代码吐出调试信息,这些可以提供帮助。由于您使用的是非控制台(网络)框架,这可能很重要,但一种快速而肮脏的方法可能是在 access.py:

中插入这样一行
open('some_temporary_file_somewhere.txt', 'wt').write('\n'.join([
    repr( request ),
    request.__module__,
    request.__class__,
])

这应该让您了解 request 的 class 定义位置的详细信息(但不一定是创建名为 request 的实际实例的文件的名称) .

here 所述,web2py 模型、控制器和视图文件由框架在已经填充了核心 API 对象的环境中执行,包括 requestresponsesessioncacheDALField、HTML 助手和表单验证器([=36= 的其他部分]],例如 Auth、Mail、Services、Scheduler 以及许多其他工具和贡献的库,都包含在模块中并照常导入)。

具体来说,request 对象是在主 WSGI 应用程序(gluon.main.wsgibase) at this line, and it is subsequently passed to gluon.main.serve_controller at this line 中(根据每个请求)创建的。serve_controller 函数将 request 对象添加到执行环境,然后在该环境中执行模型、控制器和视图文件。

除了模型、控制器和视图文件之外,您的应用程序还可以包含自己的模块。应用程序中的模块不由框架执行(它们必须被导入)——因此,这些模块必须通过从 gluon 导入来访问 web2py 核心 API 对象(依赖于请求的对象,例如 requestresponse 是通过 current 线程局部对象访问的,如 here) 所述。

查看文档的 Workflow, Libraries, and Execution environment 部分可能也会有所帮助。