【问题标题】:Retrieve Import string from a decorated classmethod从装饰的类方法中检索导入字符串
【发布时间】:2015-05-02 22:28:20
【问题描述】:

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

所以代码看起来像这样:

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)

【问题讨论】:

  • 装饰发生在类对象构建之前。那时没有课程可以发现。
  • 绑定类方法(或任何其他方法)在您将函数名称作为类或实例的属性访问时发生。 Python 绑定 late,并且是动态绑定的,而不是在您定义要用作方法的函数时。

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


【解决方案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 装饰器检查何时装饰类。

【讨论】:

    猜你喜欢
    • 2020-01-02
    • 2021-02-02
    • 2018-05-06
    • 2014-01-14
    • 1970-01-01
    • 2011-08-18
    • 2020-01-11
    • 1970-01-01
    • 2021-03-19
    相关资源
    最近更新 更多