Metaclass将classname作为参数传递

时间:2018-05-09 21:26:57

标签: python python-2.7 metaclass

我有类别:

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(?) 我可以将classname作为参数传递吗?调用这个装饰器的方法? 即如果testmethod调用metaclass装饰器并将Testclass作为参数传递。所以,如果我知道func.__name__来自特定类,那就做特定的事情。

1 个答案:

答案 0 :(得分:1)

您忘了从装饰器返回包装器。它应该是:

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

该方法已被包装器正确替换。

在您之前(现已删除)的问题中,您要求 print"此方法来自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