Python: у каждого экземпляра должен быть свой суперкласс
В Python у меня есть экземпляры такого класса, как MyClass('name1')
, MyClass('name2')
и так далее.
Я хочу сделать так, чтобы у каждого экземпляра был свой суперкласс, т.е. MyClass('name1')
быть примером Name1MyClass
а также MyClass('name2')
быть примером Name2MyClass
, Name1MyClass
а также Name2MyClass
будут динамически генерируемые подклассы MyClass
, Я не могу понять, как это сделать, потому что кажется, что Python всегда делает все, что возвращается из __new__
экземпляр этого класса. Мне тоже не понятно, как это сделать в метаклассе.
Причина, по которой я хочу это сделать, заключается в том, что я хочу определить __doc__
Строки документов на экземплярах. Но похоже что help
полностью игнорирует __doc__
в случаях; это только смотрит на классы. Таким образом, чтобы поместить разные строки документации в каждый экземпляр, мне нужно, чтобы каждый экземпляр имел свой собственный класс.
1 ответ
Я могу ошибаться, но я не думаю, что вы хотите метакласс здесь. __metaclass__
Они используются при создании класса, а не при вызове класса для создания нового экземпляра класса (или чего-то еще).
Вот ответ, используя __new__
без метакласса. Это выглядит немного странно, но, похоже, работает:
_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'))