【问题标题】:Confusion about a simple python wsgi server (wsgiref.simple_server)关于一个简单的 python wsgi 服务器的困惑 (wsgiref.simple_server)
【发布时间】:2012-07-13 08:19:44
【问题描述】:

这是一个简单的 python wsgi 服务器,在 0.0.0.0:8080 上打印出 Hello guys!!!

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 参数必须与 application 正文中的 start_response 具有相同的名称功能。

我知道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 存储在WSGIServerapplication 类变量中。

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

【问题讨论】:

    标签: python network-programming shared-libraries wsgi


    【解决方案1】:

    这里重要的 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 框架要求所有的应用程序函数接受两个参数,所以它总是用两个参数调用函数,所以你必须用两个参数定义你的函数,否则它将无法正常工作。

    【讨论】:

    • 谢谢内德。这有很大帮助,但仍然不能解释一切。在原帖中查看我的Edit
    猜你喜欢
    • 2014-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多