python decorator将函数添加到obj上的列表

2024-06-07 12:45:26 发布

您现在位置:Python中文网/ 问答频道 /正文

在python中,我需要列出类的属性列表,然后将其序列化,在类的顶部列出这些属性是很麻烦的。相反,我想用与@property相同的方式使用decorator,例如:

class MyClass(object):

    # I dont like having to do this for example
    #__list_of_props_to_serialise__ = ['my_prop',]

    @property
    @serialise
    def my_prop(self):
        return "this is my property"

    def serialise(self):
        return {f: self.getattr(f) for f in self.__list_of_props_to_serialise__}

其中,__list_of_props_to_serialise__是在类生成时由装饰器在对象上更新的,因此我不需要在开始处注释掉的行。在

问题是,当我编写decorator时,在实际调用my_prop函数之前,我无法访问类或对象,因此无法添加它。我是不是“做错了”,有没有更好的方法,或者可以用某种方法?在

如果能做到这一点,可以一些请显示一个装饰函数我可以使用,否则如果有更好的方法请给出一个例子。在

谢谢。在


Tags: ofto方法selffor属性mydef
2条回答

您可以在类之外编写修饰符,参数“self”对应于MyClass类型对象:

def serialise(func):
    def wrapper(self, *args, **kwargs):
        if func.__name__ not in self.serialisables:
            self.serialisables.append(func.__name__)
            print("Adding " + func.__name__)
        return func(self, *args, **kwargs)
    return wrapper

然后在MyClass中初始化可序列化列表:

^{pr2}$

使用属性时,其名称将添加到serialisables属性中:

>>> c = MyClass()
>>> c.my_prop
Adding my_prop
this is my property
>>> c.serialisables
['my_prop']

但是,只有在使用c.my_prop时才会添加属性的名称:

>>> c = MyClass()
>>> c.serialisables
[]

不要建立一个列表,只需向函数对象添加一个tagging属性。然后枚举类上具有该属性的所有函数。在

因为这里有property对象,因此只能在property对象的getter上找到该属性,因此需要确保访问类型而不是实例的属性,然后分别触发getter:

def serialise(func):
    func._do_serialise = True
    return func

def serialisables(obj):
    cls = type(obj)
    cls_attrs = ((name, getattr(cls, name, None)) for name in dir(obj))
    return {name: getattr(obj, name) for name, attr in cls_attrs
            if isinstance(attr, property) and getattr(attr.fget, '_do_serialise', False)}

演示:

^{pr2}$

相关问题 更多 >

    热门问题