简体   繁体   English

如何动态定义Python类的基类列表?

[英]How can I dynamically define the list of base classes for a Python class?

I have a custom Django mixin which should be imported/added to a view class only if some app is installed , eg 我有一个自定义Django mixin安装了某些应用程序时应将其导入/添加到视图类中,例如

class MyView(LoginRequiredMixin, CustomMixin, View):
    #                            ^
    #                            this is an optional mixin
    pass

How to achieve this in Django? 如何在Django中实现?

Not that this is good design practice or anything, but one way you could achieve this is attempt to import your mixin at application boot time, just as you would normally, but wrap it in a try/except so that if the app is not installed, you create a stub class of the same name that does nothing. 并不是说这是一种好的设计习惯,而是要实现的一种方法是尝试像通常那样在应用程序启动时导入mixin,但将其包装在try / except中,以便在未安装应用程序的情况下进行导入,您将创建一个不执行任何操作的同名存根类。 This way the name is resolved in either case and you won't fall over any import errors at startup time. 这样,无论哪种情况都可以解析名称,并且在启动时不会遇到任何导入错误。

Something like this: 像这样:

try:
    from conditional_app import CustomMixin
except ImportError:
    class CustomMixin(object):
        pass

class MyView(LoginRequiredMixin, CustomMixin, View):
    pass

The parameter list passed to a class definition in Python 3 supports all of the features of a function call, meaning you can use *args and **kwargs -style arguments in the class base list: 传递给Python 3中的类定义的参数列表支持函数调用的所有功能,这意味着您可以在类基础列表中使用*args**kwargs -style参数:

bases = [LoginRequiredMixin]

if apps.is_installed("some_app"):
    bases.append(CustomMixin)

class MyView(*bases, View):
    ...

Alternatively, you can use a metaclass : 另外,您可以使用一个元类

from django.apps import apps

class MixinsMeta(type):
    def __new__(cls, name, bases, namespace, **kwargs):
        # customize the `bases` tuple here..
        return super().__new__(cls, name, bases, namespace)

Then in the view: 然后在视图中:

class MyView(View, metaclass=MixinsMeta):
    ...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM