Метакласс передать имя класса в качестве параметра - PullRequest
0 голосов
/ 10 мая 2018

У меня есть метакласс как:

class Metaclass(type):
    def __new__(self, name, bases, attrs):

        for k, v in attrs.iteritems():
            if isinstance(v, types.FunctionType):
               attrs[k] = self.decorator(v)
        return super(MetaClass, self).__new__(self, name, bases, attrs)

    @classmethod
    def decorator(cls, func):
        def wrapper(*args, **kwargs):
            print(func.__name__)

Но я не могу получить func.__class__.__name__ он печатает метакласс. Я хочу получить имя класса func.__name__. Видимо, это не возможно, это Python 2.7 (?) Могу ли я передать имя класса в качестве параметра? для метода, который вызывает этот декоратор? то есть, если testmethod вызывает декоратор метакласса и передает Testclass в качестве параметра. Так что, если я знаю, func.__name__ из определенного класса, делайте конкретные вещи.

1 Ответ

0 голосов
/ 10 мая 2018

Вы забыли вернуть обертку от декоратора. Должно быть:

class Metaclass(type):
    def __new__(self, name, bases, attrs):

        for k, v in attrs.iteritems():
            if isinstance(v, types.FunctionType):
               attrs[k] = self.decorator(v)
        return super(Metaclass, self).__new__(self, name, bases, attrs)

    @classmethod
    def decorator(cls, func):
        def wrapper(*args, **kwargs):
            print(func.__name__)
        return wrapper

Теперь вы можете использовать метакласс:

>>> class TestClass(object):
    __metaclass__ = Metaclass
    def foo(self):
        return "bar"

>>> t = TestClass()
>>> x = t.foo()
foo
>>> print x
None

Метод был корректно заменен оболочкой.


В предыдущем (сейчас удаленном) вопросе, который вы задали для , напечатайте "этот метод из Testclass" . Вы можете просто передать имя класса декоратору:

class Metaclass(type):
    def __new__(self, name, bases, attrs):

        for k, v in attrs.iteritems():
            if isinstance(v, types.FunctionType):
               attrs[k] = self.decorator(v, name)
        return super(Metaclass, self).__new__(self, name, bases, attrs)

    @classmethod
    def decorator(cls, func, name):
        def wrapper(self, *args, **kwargs):
            print "%s defined in %s called from %s instance" % (func.__name__,
                name, self.__class__.__name__)
            return func(self, *args, **kwargs)
        return wrapper

Вы получаете сейчас:

>>> class TestClass(object):
    __metaclass__ = Metaclass
    def foo(self):
        return "bar"


>>> t = TestClass()
>>> x = t.foo()
foo defined in TestClass called from TestClass instance
>>> print x
bar
...