Можно ли создать класс, каждый экземпляр которого будет иметь различный тип? - PullRequest
2 голосов
/ 07 февраля 2020

Это скорее теоретический вопрос и не относится к реальной проблеме.

Учитывая, что у вас есть какой-то класс:

class A():
    pass

a = A()
type(a)
# <class '__main__.A'>

Возможно ли реализовать что-то подобное?

from random import randint

class Randomized(type):
    def __new__(cls, name, bases, attrs):
        attrs['__qualname__'] += str(randint(0, 99))
        return super(Randomized, cls).__new__(cls, name, bases, attrs)

class A(metaclass=Randomized):
    pass

a = A()
b = A()
# as I was thinking:
type(a)
# <class '__main__.A75'>
type(b)
# <class '__main__.A23'>

Пример выше не работает, как я ожидал, потому что кажется, что Randomized.__new__ вызывается только один раз:

a = A()
b = A()
type(a)
# <class '__main__.A66'>
type(b)
# <class '__main__.A66'>

Связанный PEP о метаклассах: https://www.python.org/dev/peps/pep-3115/

1 Ответ

4 голосов
/ 07 февраля 2020

Вы должны поместить __new__ в класс A для достижения желаемого поведения. Пример:

from random import randint


class A:
    def __new__(cls, *args, **kwargs):
        random_cls = type('random_name' + str(randint(0, 99)), (object,), {})
        return random_cls()


a = A()
b = A()
print(type(a))
# <class '__main__.random_name90'>
print(type(b))
# <class '__main__.random_name22'>

__new__ в метаклассе вызывается при создании класса A, но не при создании его экземпляров , как вы ожидали.

...