【问题标题】:Assigning a Method in WSGI/Python在 WSGI/Python 中分配方法
【发布时间】:2015-09-15 04:28:39
【问题描述】:

您好,我正在查看Werkzeug tutorial,我对声明有点困惑:app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/static': os.path.join(os.path.dirname(__file__), 'static') })

包含在里面:

class Shortly(object):

    def __init__(self, config):
        self.redis = redis.Redis(config['redis_host'], config['redis_port'])

    def dispatch_request(self, request):
        return Response('Hello World!')

    def wsgi_app(self, environ, start_response):
        request = Request(environ)
        response = self.dispatch_request(request)
        return response(environ, start_response)

    def __call__(self, environ, start_response):
        return self.wsgi_app(environ, start_response)


def create_app(redis_host='localhost', redis_port=6379, with_static=True):
    app = Shortly({
        'redis_host':       redis_host,
        'redis_port':       redis_port
    })
    if with_static:
        app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
            '/static':  os.path.join(os.path.dirname(__file__), 'static')
        })
    return app

那里发生了什么?为什么 app.wsgi_app 被分配给 SharedDataMiddleware 返回的任何东西?我的意思是,app.wsgi_app 不只是一个方法名吗?

任何见解将不胜感激:) 谢谢!

【问题讨论】:

    标签: wsgi werkzeug


    【解决方案1】:

    TL;DR在此示例中,通过使用SharedDataMiddleware 对象包装其入口点,将额外功能添加到Shortly 应用程序。

    长解释

    app.wsgi_app 不是方法名称。它是对方法的引用。而且由于 Python 是一种非常动态的语言,因此可以在创建对象后替换任何对象的方法。

    让我们考虑一个简单的例子:

    class App:
        def run(self, param):
            print(param)
    
    app = App()
    app.run('foo')  # prints 'foo'        
    
    original_run = app.run  # save a reference to the original run method
    
    def run_ex(param):
        print('run_ex')      # add our extra functionality
        original_run(param)  # call the original one
    
    app.run = run_ex
    app.run('foo')  # prints 'run_ex' and then 'foo'
    

    因此,通过这种方式,我们可以轻松地将应用程序的方法run 替换为常规函数。

    现在,让我们回到Werkzeug。正如您从WSGI specification 中了解到的,应用程序必须是具有特定签名的可调用。而Shortlywsgi_app 方法是所需的可调用对象。然而,有人想通过SharedDataMiddleware 中间件向Shortly 应用程序添加额外的功能。如果你 look closer 到它,你会看到,它是一个带有 __call__ 方法的普通类。因此,SharedDataMiddleware 类的所有对象都可以被调用。

    middleware = SharedDataMiddleware(...)  # create an object
    middleware(...)  # call the object. It can be slightly confusing at a first glance
    

    所以,现在您可以看到SharedDataMiddleware 的任何对象本身就是WSGI 应用程序。而且由于您已经知道如何替换app 的主要方法wsgi_app,您唯一需要做的一件事就是存储对原始方法Shortly.wsgi_app 的引用,以便以后能够调用它。这是通过将其传递给SharedDataMiddleware 构造函数来完成的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-20
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 2020-01-14
      • 2021-06-17
      相关资源
      最近更新 更多