【问题标题】:How to initialize classes (not instances) in Python?如何在 Python 中初始化类(不是实例)?
【发布时间】:2011-09-05 05:41:38
【问题描述】:

我只想在加载类后合并来自当前类和继承类的约束(而不是每个对象!)。

class Domain(Validatable):

    constraints = {...}

为此,我定义了一个方法_initialize_class_not_instance,每个类都应该调用一次:

class Validatable:

    @classmethod
    def _initialize_class_not_instance(cls):
        # merge constraints from derived class and base classes
        pass

    __class__._initialize_class_not_instance() # doesn't work
    # Validatable._merge_constraints() # doesn't work too

问题是__class__ 在此上下文中不存在并且Validatable 也没有定义。但我想避免,我的 API 的用户必须显式调用初始化方法或必须使用额外的类装饰器。

任何想法如何初始化类?

【问题讨论】:

  • 请注意,类实例,通常它们是type 的实例,但正如@Ignacio 指出的那样,它们可以是type 的自定义子类的实例。

标签: python oop inheritance class-method


【解决方案1】:

使用元类。

class MetaClass(type):
  def __init__(cls, name, bases, d):
    type.__init__(cls, name, bases, d)
    cls.foo = 42

class MyClass(object):
  __metaclass__ = MetaClass

print MyClass.foo

【讨论】:

  • 记录一下,在python3中是MyClass(object, metaclass=MetaClass)
  • 为什么需要元类?为什么不在“MyClass”的定义后面加上“MyClass.foo = 42”语句?
【解决方案2】:

我最终得到了一个没有继承的类装饰器。这个装饰器合并了当前类和继承类的约束,并覆盖了__init__方法:

def validatable(cls):

    # merge constraints from derived class and base classes here ...

    original_init = cls.__init__
    def init_to_insert(self, *args, **keywords):
        self.errors = {}
        original_init(self, *args, **keywords)   
    cls.__init__ = init_to_insert
    return cls

这是我解决方案的关键,因为装饰器必须修改类(合并约束和插入方法)和实例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-12
    • 2017-02-09
    • 2012-09-21
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多