'''
В объектно-ориентированном программировании метакласс - это класс,  которого экземпляры являются классами.
С помощью метакласса мы можем определять свойства, которые должны быть добавлены к новым классам, которые определены в нашем коде.

Например, следующий пример кода метакласса добавляет свойство hello к каждому классу, который использует этот метакласс в качестве своего шаблона. Это означает, что новые классы, являющиеся экземплярами этого метакласса, будут иметь свойство hello без необходимости определять его сами.
'''


class HelloMeta(type):
    def hello(cls):
        print("greetings from %s, a HelloMeta type class" % (type(cls())))

    def __call__(self, *args, **kwargs):
        cls = type.__call__(self, *args)

        setattr(cls, "hello", self.hello)

        return cls

class TryHello(object, metaclass=HelloMeta):
    def greet(self):
        self.hello()


'''
Метапрограммирование - это код, который управляет кодом.
Термин «метапрограммирование» относится к способности программы знать себя или манипулировать собой. Python поддерживает форму метапрограммирования для классов, называемых метаклассами.

'''