【问题标题】:Raise exception while defining a class improperly错误定义类时引发异常
【发布时间】:2016-02-19 17:38:10
【问题描述】:

我如何编写一个 mixin,如果使用这个特定 mixin 的类没有正确创建,它会引发一个异常。

如果我在 mixin 的 __init__ 或 __new__ 方法中进行这些检查和平衡,当这个错误的类尝试创建实例时会引发异常。这已经晚了,理想情况下,当编译器检测到错误的类时需要抛出异常。 (假设,如何检测一个类是否可以接受是一件小事)

说明问题

class ASampleMixin:
    """
    A sample docstring
    """

    def a_method(self):
        raise NotImplementedError

    def class_rule(self):
        if something is wrong:
            return False
        return True 

    # more methods

class AClass(ASampleMixin, BaseClass):
    """
    This class should satisfy a condition specified in class_rule method of the mixin
    """
    # some methods

我现在正在执行 mixin 的 init 方法中的检查。如果规则返回 False,则会引发异常。现在这需要在解释器读取 AClass 时完成,而不是在我尝试创建 AClass 实例时完成。

即使在 Python 3.5 等动态类型语言中也有可能吗?

【问题讨论】:

  • 谢谢。更正了它。没有关注它,它就流出来了。

标签: python oop python-3.x metaprogramming


【解决方案1】:

这听起来好像您想创建一个自定义元类,在创建类对象时执行检查。请参阅documentation for metaclasses

【讨论】:

  • 有趣...所以基本上添加这个检查和引发异常可以在元类的初始化中完成。 mixin 和 Aclass 可以都派生自不同的元类吗?
  • @iankit 如果这样做,则子类的元类是基础的派生度最高的元类,它(从文档中)是“从明确指定的元类中选择的(如果有)和所有指定基类的元类(即类型(cls))。最派生的元类是所有这些候选元类的子类型。如果没有一个候选元类符合该标准,则类定义将因 TypeError 而失败。”
【解决方案2】:

作为参考的元类示例:

class CustomType(type):
    def __call__(cls, *args, **kwargs):
        if not CustomType.some_rule(kwargs.pop('some_attr', None)):
            raise Exception('Abort! Abort!')
        return super(CustomType, cls).__call__(*args, **kwargs)

    @staticmethod
    def some_rule(var):
        if type(var) is not str:
            return False
        return True


class A(object):
    __metaclass__ = CustomType


class B(A):
    pass

b = B(some_attr='f') # all is well
b = B() # raises 

【讨论】:

  • 这不能回答问题,在您的代码中,当从类创建实例时会引发异常。这是一个不希望的结果。我本可以通过默认方式实现这一点。
猜你喜欢
  • 2015-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
相关资源
最近更新 更多