python,如何批量创建类?

标签 python

我是python新手,我想创建3个类,如下:

class ProtectTemplate(TemplateView):
    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProtectTemplate, self).dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        context['phone'] = xxx
        return context


class ProtectList(ListView):
    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProtectList, self).dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        context['phone'] = xxx
        return context


class ProtectDetail(DetailView):
    @method_decorator(login_required)
    def dispatch(self, *args, **kwargs):
        return super(ProtectDetail, self).dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        context['phone'] = xxx
        return context

我觉得这太可怕了。所以我尝试这样做:

login_class = [
    ('ProtectTemplate', TemplateView),
    ('ProtectList', ListView),
    ('ProtectDetail', DetailView),
]

for c, v in login_class:
    class c(v):
        @method_decorator(login_required)
        def dispatch(self, *args, **kwargs):
            return super(self.__class__, self).dispatch(*args, **kwargs)

        def get_context_data(self, **kwargs):
            context['phone'] = xxx
            return context

但是它不起作用。有没有办法批量创建3个类?

最佳答案

你的循环是正确的方法,但是你正在重新绑定(bind)c(没有为类设置新的全局名称),你不能使用变量来命名中的类class 语句(该类将被称为 c),并且使用 super(self.__class__, self)lead to infinite recursion issues .

您可以改用工厂函数,然后使用 globals() 字典将新创建的类添加到全局命名空间。该函数提供了一个闭包,因此我们可以将实际的类对象传递给 super():

def _create_login_class(name, base):
    class LoginCls(base):
        @method_decorator(login_required)
        def dispatch(self, *args, **kwargs):
            return super(LoginCls, self).dispatch(*args, **kwargs)

        def get_context_data(self, **kwargs):
            context['phone'] = xxx
            return context

    LoginCls.__name__ = name
    LoginCls.__qualname__ = name   # Python 3
    return LoginCls

_login_class = [
    ('ProtectTemplate', TemplateView),
    ('ProtectList', ListView),
    ('ProtectDetail', DetailView),
]

for _name, _base  in _login_class:
    globals()[_name] = _create_login_class(_name, _base)

super(LoginCls, self) 表达式在父函数命名空间中查找 LoginCls 作为非本地名称,因此始终使用正确的上下文来查找下一个类在 MRO 中。

我使用前导下划线名称来指示工厂函数以及 _login_class_name_base 名称是模块的实现细节.

演示:

>>> class Base:
...     def dispatch(self, *args, **kwargs): print('Base.dispatch({}, {}) called'.format(args, kwargs))
...
>>> class TemplateView(Base): pass
...
>>> class ListView(Base): pass
...
>>> class DetailView(Base): pass
...
>>> method_decorator = lambda *args: lambda f: f
>>> xxx = 'xxx'
>>> login_required = 'login_required'
>>> def _create_login_class(name, base):
...     class LoginCls(base):
...         @method_decorator(login_required)
...         def dispatch(self, *args, **kwargs):
...             return super(LoginCls, self).dispatch(*args, **kwargs)
...         def get_context_data(self, **kwargs):
...             context['phone'] = xxx
...             return context
...     LoginCls.__name__ = name
...     LoginCls.__qualname__ = name   # Python 3
...     return LoginCls
...
>>> _login_class = [
...     ('ProtectTemplate', TemplateView),
...     ('ProtectList', ListView),
...     ('ProtectDetail', DetailView),
... ]
>>> for _name, _base  in _login_class:
...     globals()[_name] = _create_login_class(_name, _base)
...
>>> ProtectTemplate
<class '__main__.ProtectTemplate'>
>>> class SubclassDemo(ProtectTemplate):
...     def dispatch(self, *args, **kwargs):
...         print('SubclassDemo.dispatch({}, {}) called'.format(args, kwargs))
...         super(SubclassDemo, self).dispatch(*args, **kwargs)
...
>>> SubclassDemo().dispatch(42, spam='ham')
SubclassDemo.dispatch((42,), {'spam': 'ham'}) called
Base.dispatch((42,), {'spam': 'ham'}) called

关于python,如何批量创建类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40628484/

相关文章:

python - 在 Python 中模拟指针

python - 如何在Databricks中使用os.walk()来计算Azure datalake中的目录大小

python - 限制 dask 计算使用的 CPU 数量

python - token 身份验证不适用于 Django Rest 框架

python - 停止页面加载 Python/Selenium/PhantomJS

python - 是否有更多 pythonic 方法来编写只更新变量的 while 循环?

python - 使用 scikit.mlpregressor 训练多个数据集

python - 反向使用 Python 格式字符串进行解析

Python:如何在使用正则表达式时跳过有多余字符的行?

python - 在 App Engine NDB 模型中,是否需要显式缓存对相关模型的引用以最小化查询成本并优化性能?