【问题标题】:Metaclass pass classname as parameter元类传递类名作为参数
【发布时间】:2018-10-20 02:23:19
【问题描述】:

我有类似的元类:

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__ 来自特定班级,请做特定的事情。

【问题讨论】:

  • func.__class__ 不是定义函数的类;是types.FunctionType,函数对象本身的类。

标签: python python-2.7 metaclass


【解决方案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

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


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

【讨论】:

  • name 确实给了我方法所在的类的名称。即如果test1 方法在TestChild1 类中,我将test1 称为``` testChild1Class = TestChild1() testChild1Class.nest1() ``` 我得到name 作为TestChild1。但是,如果我在 testChild1Class.test1parent() 这样的父类中调用方法 test1parent,我会得到父类的名称。我可以在这里获取子类名称吗?
  • func.__name__ 是通过构造声明方法的类的名称。如果你想要当前对象的类名,只需使用self.__class__.__name__,如编辑后的帖子所示
猜你喜欢
  • 2021-09-07
  • 2021-02-12
  • 1970-01-01
  • 1970-01-01
  • 2018-01-04
  • 1970-01-01
  • 1970-01-01
  • 2015-07-29
相关资源
最近更新 更多