1

在 Python 中,我目前有一个类的实例,MyClass('name1')诸如此类MyClass('name2')

我想使每个实例都有自己的超类,即我想MyClass('name1')成为的一个实例Name1MyClassMyClass('name2')成为Name2MyClass. Name1MyClass并且Name2MyClass将是动态生成的子类MyClass。我不知道如何做到这一点,因为似乎 Python 总是会生成从__new__该类的实例返回的任何内容。我也不清楚如何在元类中做到这一点。

我想这样做的原因是我想__doc__在实例上定义文档字符串。但似乎help完全忽略__doc__了实例;它只看类。因此,要在每个实例上放置不同的文档字符串,我需要让每个实例都有自己的自定义类。

4

1 回答 1

2

我可能是错的,但我不认为你想要一个元类。 __metaclass__es 在创建类时使用,而不是在您调用类来构造类的新实例(或其他东西)时使用。

__new__这是一个没有元类的答案。感觉有点hacky,但它似乎工作:

_sentinel = Ellipsis
class MyClass(object):
    def __new__(cls, name):
        if name is _sentinel:
            return object.__new__(cls)
        else:
            instance = type(name + cls.__name__, (MyClass,), {})(_sentinel)
            # Initialization goes here.
            return instance

print type(MyClass('name1'))
print type(MyClass('name2'))

这里有一个问题——初始化新实例的所有业务逻辑都必须在__new__. 由于__new__返回的类型与其绑定的类不同,__init__因此不会被调用。


另一种选择是创建一个类工厂:

class MyClass(object):
    pass

def class_factory(name):
    new_cls = type(name + MyClass.__name__, (MyClass,), {})
    return new_cls() # Or pass whatever you want in here...

print type(class_factory('name1'))
print type(class_factory('name2'))

最后,您甚至可以创建一个非__new__类方法:

class MyClass(object):
    @classmethod
    def class_factory(cls, name):
        new_cls = type(name + cls.__name__, (cls,), {})
        return new_cls() # Or pass whatever you want in here...

print type(MyClass.class_factory('name1'))
print type(MyClass.class_factory('name2'))
于 2013-10-15T22:46:22.150 回答