【问题标题】:What is the appropriate way to intercept WSGI start_response?拦截 WSGI start_response 的适当方法是什么?
【发布时间】:2010-03-05 06:11:56
【问题描述】:

我有 WSGI 中间件,它需要捕获中间件内部层通过调用 start_response 返回的 HTTP 状态(例如 200 OK)。目前我正在做以下事情,但滥用列表对我来说似乎不是“正确”的解决方案:

类 TransactionalMiddlewareInterface(object):
    def __init__(self, application, **config):
        self.application = 应用程序
        self.config = 配置

    def __call__(self, environ, start_response):
        状态 = []

        def local_start(stat_str, headers=[]):
            status.append(int(stat_str.split('')[0]))
            返回 start_response(stat_str, headers)

        尝试:
            结果 = self.application(环境,local_start)

        最后:
            状态 = 状态 [0] 如果状态为其他 0

            如果状态 > 199 和状态 

列表滥用的原因是我无法从完全包含的函数中为父命名空间分配新值。

【问题讨论】:

    标签: python wsgi middleware correctness


    【解决方案1】:

    您可以将状态分配为local_start 函数本身的注入字段,而不是使用status 列表。我用过类似的东西,效果很好:

    class TransactionalMiddlewareInterface(object):
        def __init__(self, application, **config):
            self.application = application
            self.config = config
    
        def __call__(self, environ, start_response):
            def local_start(stat_str, headers=[]):
                local_start.status = int(stat_str.split(' ')[0])
                return start_response(stat_str, headers)
            try:
                result = self.application(environ, local_start)
            finally:
                if local_start.status and local_start.status > 199:
                    pass
    

    【讨论】:

    • 这是一个很棒的解决方案!谢谢。
    【解决方案2】:

    只需使用带有nonlocal 键的简单变量即可。

    class TransactionalMiddlewareInterface(object):
        def __init__(self, application, **config):
            self.application = application
            self.config = config
    
        def __call__(self, environ, start_response):
            status = 0
    
            def local_start(stat_str, headers=[]):
                nonlocal status
                status = int(stat_str.split(' ')[0])
                return start_response(stat_str, headers)
    
            try:
                result = self.application(environ, local_start)
    
            finally:
                if status > 199 and status 
    

    【讨论】:

    • 11 年前接受的答案完全避免了命名空间查找操作(不使用 nonlocal 关键字,因此与 Python 2 兼容)并且不会弄乱比较顺序或中断。更新≠总是更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 2011-05-28
    • 2019-11-12
    • 2013-09-22
    • 1970-01-01
    • 2013-05-23
    相关资源
    最近更新 更多