从装饰的classmethod中检索导入字符串

时间:2015-03-02 14:19:15

标签: python decorator python-decorators class-method inspect

我正在尝试检索装饰@classmethod中的import-string,以在管道系统中注册此字符串。但是当我在装饰器函数中检查函数对象时,无法找到有关类对象或类名的任何信息。

所以代码看起来像这样:

def import_string_decorator(**opt_kwargs):

    def wrap(f):

        # Here is the problem
        if inspect.ismethod(f):
            class_name = f.im_self.__name__
            import_string = f.__module__ + "." class_name + "." + f.__name__
            # But this doesn't work because f no longer is a <bound method to class 'SomeClass'> but is a regular <function>
        else:
            import_string = f.__module__ + "." + f.__name__

        # Register the string
        do_something(import_string, **opt_kwargs)

        def wrapped_f(*args, **kwargs):

            f(*args, **kwargs)

        return wrapped_f

    return wrap


# Decorated Class
opt_dict = {"some": "values"}

class SomeClass(object):

    @classmethod
    @import_string_decorator(**opt_dict)
    def double_decorated_function(cls, *args, **kwargs):

        pass

但我还没有找到一种方法来检索修饰函数的类对象。 inspect.ismethod()函数也会返回False,因为它会检查下面的isinstance(types.MethodType)

1 个答案:

答案 0 :(得分:1)

使用函数装饰器无法实现您想要的功能。在构建类对象之前,创建并装饰了函数对象。 Python首先执行类主体,然后生成的名称形成类属性。

当您使用descriptor protocol作为属性访问名称时,方法的绑定会动态发生。

您需要挂钩创建类才能访问类名;你可以使用类装饰器,或使用元类。您可以将这些技术与函数装饰器结合使用,如果这样可以更容易:

@registered_class
class SomeClass(object):

    @classmethod
    @import_string_decorator(**opt_dict)
    def double_decorated_function(cls, *args, **kwargs):
        pass

import_string_decorator可以为registered_class装饰器注释函数(例如,你可以为它设置一个属性)来检查类的装饰时间。