5

这是一个简单的 python wsgi 服务器,可以Hello guys!!!0.0.0.0:8080.

from wsgiref.simple_server import make_server

content = 'Hello guys!!!'

def application(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return [content]

server = make_server('0.0.0.0', 8080, application)
server.serve_forever()

查看此代码时会出现几个问题:

  1. make_server该函数如何仅使用函数名称application?我看不出它是如何做任何其他事情的,然后返回"<function application at 0x7f71686286e0>"字符串(application.__repr__() method函数对象的)。

  2. 为什么应用程序函数定义定义environ为参数,而不是在这个函数中使用,甚至没有在application以后的函数调用中设置?

  3. 据我了解,start_response函数定义中的参数在这里用作一种标识符,这将是函数的名称,它设置稍后在make_server函数调用中需要的其他属性。标准库中定义的功能在哪里?(我已经检查了相关模块的来源,但我不明白它是在哪里完成的)

观察:更改environ函数定义中的参数不会改变代码行为的任何内容,但是参数必须与函数体中的start_response名称相同。start_responseapplication

我知道os.environ是一本字典,但我在 python 标准库中找不到它的调用位置。如果environ参数是必要的并且是唯一可行的第一个参数,我不明白为什么他们会要求您environ每次都明确命名第一个参数(),它会给您一种错觉,即使用不同的参数会影响其行为。我知道“显式优于隐式”-python 策略,但在这里我认为它是无用且令人困惑的。

编辑

由于 Ned 的回答,我现在通过查看make_server('0.0.0.0', 8080, application)创建WSGIServer诸如wsgiref.simple_server.WSGIServer((host, port), handler_class)). 更深入地看,我发现初始化方法是继承自BaseServer. BaseServer 实例具有server_addressRequestHandlerClass作为实例变量等。函数对象application存储在 的application类变量中WSGIServer

但我仍然找不到这个application类变量在 python 源代码中的其他地方使用。(我已经搜索了所有包含父类的类定义的模块WSGIServer)有人知道它在哪里使用吗?发现这可能会回答我所有的问题。

4

1 回答 1

3

这里重要的 Python 概念是函数和其他任何东西一样都是对象,并且可以分配给变量:

>>> def double(x):
...     return 2*x
...

>>> my_fn = double
>>> my_fn(4)
8

当您使用不带括号的函数名称时,您只是在谈论该函数,而不是调用它。

在这一行:

server = make_server('0.0.0.0', 8080, application)

application是一个函数,您将它作为一个值传递给make_server,稍后将能够调用它。这就是您的应用程序的调用方式。传递给您的application函数的值之一是另一个函数,称为start_response. 这是 WSGI 作者编写的一个函数,他们将其提供给您调用,您可以使用该行

start_response('200 OK', [('Content-Type', 'text/plain')])

您的application函数必须接受两个参数,通常称为 environ 和 start_response。您不使用 environ 值,但更复杂的 WSGI 应用程序会。WSGI 框架要求所有的应用程序函数接受两个参数,所以它总是用两个参数调用函数,所以你必须用两个参数定义你的函数,否则它将无法正常工作。

于 2012-07-13T13:20:48.067 回答