Экземпляры создаются специальными объектами, называемыми «классами». Это означает, что классы также являются объектами и могут быть изменены, как мы изменяем экземпляры, с той лишь разницей, что если мы изменяем класс, это влияет на все экземпляры, созданные из класса.
>>> class Foo: >>> pass >>> firstFoo = Foo() >>> Foo.bar = 1 >>> print(firstFoo.bar) 1 >>> secondFoo = Foo() >>> print(secondFoo.bar) 1 >>> secondFoo.a = 1 >>> print(secondFoo.a) 1 >>> print(firstFoo.a) AttributeError: Foo instance has no attribute 'a'
Если экземпляры создаются классами, классы создаются специальными объектами, называемыми «метаклассами». Метапрограммирование - это изменение способа создания классов с помощью метаклассов.
Как?
Метакласс по умолчанию --type
, и он обычно используется для создания классов, которые вы пишете.
class Foo: pass
такой же как:
Foo = type('Foo', (), {})
а также
>>> class B(list): >>> x = 1 >>> def hi(self, name): >>> print('hi', name) >>> def hii(self, name): >>> print('hi', name) >>> def fake_init(self): >>> print('Fake init') >>> C = type('C', (list,), {'x': 1, 'hii': hii, '__init__': fake_init}) >>> b = B() 1 >>> b.append(1) >>> print(b.x) 1 >>> b.hi('B') ('hi', 'B') >>> c = C() Fake init >>> c.append(1) >>> print(c.x) 1 >>> c.hii('C') ('hi', 'C')
В приведенном выше коде показано, как мы можем использовать метакласс (в данном случае «тип») для создания классов. Метапрограммирование работает, добавляя ваши собственные операции к созданию классов, создавая подкласс метакласса type
и вставляя его в процесс создания классов с помощью «ловушки метакласса».
В Python 3 ловушка метакласса - это аргумент ключевого слова metaclass
в списке базовых классов определения класса. Если вы передадите класс в качестве аргумента ключевого слова в списке базовых классов в определении вашего класса, class B(metaclass=MyMetaClass):
python вызовет его после первоначального создания класса, передав объект класса, имя класса, список базовых классов и словарь пространства имен.
>>> def custom_func(self): >>> print('Yeeehaaa') >>> class MyMetaClass(type): >>> def __init__(cls, name, base_classes, namespace): >>> super(MyMetaClass, cls).__init__(name, base_classes, namespace) >>> cls.custom_func = custom_func >>> class FooBar(metaclass=MyMetaClass): >>> pass >>> bar = FooBar() >>> bar.custom_func() Yeeehaaa
Это основы метапрограммирования. Спасибо за прочтение :)
Ссылка: https://python-3-patterns-idioms-test.readthedocs.io/en/latest/Metaprogramming.html