代码之家  ›  专栏  ›  技术社区  ›  user2661518

元类将classname作为参数传递

  •  0
  • user2661518  · 技术社区  · 7 年前

    我有元类,如:

    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作为参数传递吗?对于调用此装饰器的方法? i、 e.如果 testmethod 调用元类装饰器并传递 Testclass 作为参数。所以如果我知道 职能__名称__ 就是从特定的班级做特定的事情。

    1 回复  |  直到 7 年前
        1
  •  1
  •   Serge Ballesta    7 年前

    你忘了从装饰师那里退回包装纸。它应该是:

    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