Skip to main content
 首页 » 编程设计

Python 共享属性父/子

2025年05月04日8TianFang

不好意思问,但我正在使用 webapp2,我正在设计一个解决方案,以便更容易定义路由 based on this google webapp2 route function .但这完全取决于能够在子级定义 TYPE_NAME。这个想法是 parent 设置一切, child 只需要实现 _list 功能。我遇到的问题是 TYPE_NAME is None 我需要它作为 child 。

#main WSGI is extended to have this function  
class WSGIApplication(webapp2.WSGIApplication): 
    def route(self, *args, **kwargs): 
        def wrapper(func): 
            self.router.add(webapp2.Route(handler=func, *args, **kwargs)) 
            return func 
 
        return wrapper 

from main import application 
class ParentHandler(RequestHandler): 
    TYPE_NAME = None 
 
    @application.route('/', name="list_%s" %TYPE_NAME) 
    def list(self): 
          return self._list() 
 
class ChildHandler(ParentHandler): 
    TYPE_NAME = 'child' 
 
    def _list(self): 
         return [] 

我尝试了几个使用“类属性”的解决方案,但没有成功。开放给其他想法,我基本上只需要子类继承装饰属性并执行它们。

编辑:

对于所有坐在座位边缘想知道我如何解决这个问题的人,我无法从装饰器中获得我需要的一切,所以我最终使用了元。我还添加了一个 _URLS 参数以允许添加额外的“路由”。它将 custom 函数映射到路由。真的很想使用装饰器,但无法让它工作。

class RequestURLMeta(type): 
    def __new__(mcs, name, bases, dct): 
        result = super(RequestURLMeta, mcs).__new__(mcs, name, bases, dct) 
        urls = getattr(result, '_URLS', {}) or {} 
        for k,v in urls.iteritems(): 
            template = v.pop('template') 
            app.route(getattr(result, k), template, **v) 
 
        if getattr(result, 'TYPE_NAME', None): 
            app.route(result.list, result.ROOT_PATH, methods=['GET'],name="%s" % result.TYPE_NAME) 
        #other ones went here.. 
 
    return result 
 
class ParentHandler(RequestHandler): 
    __metaclass__ = RequestURLMeta 
 
 
class ChildHandler(ParentHandler): 
    TYPE_NAME = 'child' 
    _URLS = { 'custom': '/custom', 'TYPE_NAME': 'custom_test' } 
    def _list(self): 
        return [] 
    def custom(self):  pass 

请您参考如下方法:

我认为要让它工作,你需要使用 metaclass .它可能类似于以下内容(未经测试):

from main import application 
 
class RouteMeta(type): 
    def __new__(mcs, name, bases, dct): 
        type_name = dct.get("TYPE_NAME") 
        if type_name is not None: 
            @application.route('/', type_name) 
            def list(self): 
                return self._list() 
            dct["list"] = list 
        return super(RouteMeta, mcs).__new__(mcs, name, bases, dct) 
 
class ParentHandler(RequestHandler): 
    __metaclass__ = RouteMeta 
 
class ChildHandler(ParentHandler): 
    TYPE_NAME = 'child' 
 
    def _list(self): 
         return [] 

list() 方法不是 ParentHandler 的属性,而是为继承自 ParentHandler 的类动态创建的,并且具有 TYPE_NAME 已定义。

如果 RequestHandler 也使用自定义元类,则让 RouteMeta 继承自 RequestHandler.__metaclass__ 而不是 type。