在定义python类时从方法访问它

时间:2016-07-19 04:37:18

标签: python methods reflection

我想访问要定义哪个方法的类。例如,这可以用于为具有装饰器的方法创建别名。这个特殊情况可以在不使用装饰器(alias = original_name)的情况下实现,但我想使用装饰器,主要是因为在顶部的方法定义旁边可以看到别名,当方法定义很长时很有用。

def method_alias(*aliases):
    def aliased(m):
        class_of_m = ??? # GET class of this method
        for alias in aliases:
            setattr(class_of_m, alias, m)
        return m
    return aliased

class Test():
    @method_alias('check', 'examine')
    def test():
        print('I am implemented with name "test"')

后来,我发现here上面的内容可以通过使用两个装饰器来实现(首先将别名存储为方法属性,稍后在创建类时,将属性添加到类中)。可以在不修饰课程的情况下完成,即只修饰方法吗?这需要访问装饰器中的类名。

1 个答案:

答案 0 :(得分:0)

简短的回答是否定的。在创建类对象之前评估类主体的内容,即创建函数test并将其传递给装饰器,而不存在类Test。因此装饰者无法获得对它的引用。

为了解决方法混叠的问题,我想到了三种方法:

  • 使用链接描述的类装饰器。
  • 使用元类,它允许您在创建类对象之前修改类“__dict__”。 (实现元类类实际上是覆盖了类对象的默认构造函数,请参阅here。此外,Python 3中的元类用法语法也发生了变化。)
  • __init__的每个实例在Test方法中创建别名。

第一种方法可能是最直接的方法。我写了另一个例子。它基本上与您的链接相同,但更加精简,以使其更清晰。

def alias(*aliases):
    def decorator(f):
        f.aliases = set(aliases)
        return f
    return decorator

def apply_aliases(cls):
    for name, elem in list(cls.__dict__.items()):
        if not hasattr(elem, 'aliases'):
            continue
        for alias in elem.aliases:
            setattr(cls, alias, elem)
    return cls

@apply_aliases
class Test(object):
    @alias('check', 'examine')
    def test(self):
        print('I am implemented with name "test"')

Test().test()
Test().check()
Test().examine()