如何编写一个单功能工具来检查 cherrypy 中的 class 变量

How to write a one function tool that does a check on a class variable in cherrypy

我找不到让它工作的方法。我认为问题在于如何将 class 变量或 class 引用(self)传递给函数。代码类似如下:

def isconnected(classref):
    if not classref.serialObject:
        raise cherrypy.HTTPError("403 Forbidden")

cherrypy.tools.isconnected = cherrypy.Tool('before_handler', isconnected)

然后在应用程序中class,应该这样使用:

class Controller(object):
    def __init__(self):
        self.serialObject = None

    @cherrypy.expose
    @cherrypy.tools.isconnected(self.serialObject)
    def serialVRead(self):
        # code here
        pass

换句话说,我基本上想在调用普通处理程序之前检查资源是否可用。另外,我需要它作为一个工具,因为我还有一些其他方法也想像那样装饰。

此外,我还想知道是否可以使用不同于引发 HTTPError 异常的解决方案来阻止正常处理程序执行。我尝试返回 True 或 False 但没有成功。

请让我知道这是否可行,或者是否有更好的方法来实现这一点。谢谢。

PD。我是运行 Cherrypy的最新版本(我觉得是3.3)

我认为您应该通过 CherryPy Plugin 与串行对象进行交互,并与以下内容进行通信:

serial_port = cherrypy.engine.publish('acquire_serial_port')

插件的理念是跨请求共享资源、封装和可重用。

您甚至可以将其混合在仅引用串行插件已发布频道的工具中。

1) 您可以像这样从cherrypy.serving.request.handler 中检索当前处理程序所属的实例:

#!/usr/bin/env python
# -*- coding: utf-8 -*-


import cherrypy


config = {
  'global' : {
    'server.socket_host' : '127.0.0.1',
    'server.socket_port' : 8080,
    'server.thread_pool' : 8
  }
}


def isconnected():
  instance = cherrypy.serving.request.handler.callable.__self__
  if not instance.instanceAttr:
    raise cherrypy.HTTPError("403 Forbidden")

cherrypy.tools.isconnected = cherrypy.Tool('before_handler', isconnected)


class App:

  instanceAttr = None


  def __init__(self):
    self.instanceAttr = 123

  @cherrypy.tools.isconnected()
  @cherrypy.expose  
  def index(self):
    return '''foo'''


if __name__ == '__main__':
  cherrypy.quickstart(App(), '/', config)

2) 通常在Python中,装饰器在函数成为实例方法之前对其进行操作。如果您需要访问装饰器中的实例,则需要实现 descriptor protocol (see question about it)。由于 CherryPy 工具建立在装饰器之上但有其自己的工作流程,因此描述符机制可能无法正常工作。

3) 有条件地避免正常处理程序使用 cherrypy._cptools.HandlerTool (docs, wiki, ).