我正在尝试减少我的金字塔视图中的代码编写,并且我试图通过工厂函数来完成。
因此,我的 views.py :
中没有这样的内容class MyView(object):
def __init__(self, request):
self.request = request
@view_config(route_name='view', renderer='templates/view.pt')
def get(self):
return dict(msg='Hello!')
我试着改变这样的事情:
def factory(cls_name, rtn, rndr, myfun):
class Cls(object):
def __init__(self, request):
self.request = request
@myfun(route_name=rtn, renderer=rndr)
def get(self):
return dict(msg='Hello!')
Cls.__name__ = cls_name
return Cls
MyView = factory('MyView', 'view', 'templates/view.pt', view_config)
显然,原因是我最终会拥有许多可以使用相同类功能的类,并且我希望减少我的代码编写。如果您要求我使用继承,那么我就不知道如何配置我的派生类以获得参数化装饰器(如myfun
)。从本质上讲,我需要像C ++中的模板一样。
所以,即使上面的第二个片段没有产生任何错误,对我来说似乎工作得很好,当我尝试在我的测试网站中运行它时(通过用第二个片段替换第二个片段),金字塔不理解路线,所以我得到404 error
。根据错误,我认为我的问题可能与金字塔如何解析 views.py 文件以查找view_config
装饰器有关,但我不确定如何解决它。
我的 __ init __。py 的主要功能是这样的:
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
config = Configurator(settings=settings)
config.add_route('view', '/')
config.scan()
return config.make_wsgi_app()
非常感谢任何帮助,所以提前感谢所有人!
答案 0 :(得分:1)
代码无效的最可能原因是Pyramid在启动时执行 scan 进程的详细信息,以查找和处理所有@view_config
装饰器。首先,@view_config
docstring说:
``view_config`` will work ONLY on module top level members
because of the limitation of ``venusian.Scanner.scan``.
所以我猜你的类在启动过程中创建得太晚,或者动态生成的类中的某些东西会混淆venusian。如果您查看venusian
的源代码,您可以找到原因。
但是,我想指出这种方法让我感觉有点递归...... Pyramid中有一些方法可以在没有任何装饰器的情况下注册视图。然后,Pyramid的作者在其上添加了一层“语法糖”,以简化最常见的用例,并能够通过简单地添加装饰器来注册视图。然后你开始对抗那些装饰器,以便能够通过看起来像函数调用来注册视图:)
看看pyramid.config.Configurator.add_view() - 它看起来非常像你的“工厂功能”,但如果你愿意的话,你可以在它周围写一个简单的包装。
class MyView(object):
def __init__(self, request):
self.request = request
def get(self):
return dict(msg='Hello!')
config.add_view(MyView, attr='get', route_name='view_cats', renderer='templates/view_cats.pt')
config.add_view(MyView, attr='get', route_name='view_dogs', renderer='templates/view_dogs.pt')