Python 仅将装饰器应用于类属性

Python 仅将装饰器应用于类属性,python,python-decorators,Python,Python Decorators,不确定这是否可能,但我想在python类中复制java中@annotations的思想。目标是迭代该类中的所有属性,并返回那些用自定义装饰器(例如@render)“标记”的属性。因此,在本例中,我可以定义一个通用函数来呈现通用UI/视图模板,以仅显示任何类的呈现属性 在这个虚构的代码中,Item类将是: class Item: def __init__(self): self.id = 100 @render self.desc = 'in

不确定这是否可能,但我想在python类中复制java中@annotations的思想。目标是迭代该类中的所有属性,并返回那些用自定义装饰器(例如@render)“标记”的属性。因此,在本例中,我可以定义一个通用函数来呈现通用UI/视图模板,以仅显示任何类的呈现属性

在这个虚构的代码中,Item类将是:

class Item:
    def __init__(self):
        self.id = 100
        @render
        self.desc = 'info about'
        @render
        self.title = 'product x'
        self.vender_ref = 'af2k102hv813'

并且只有标题描述将显示/返回。实现此功能的方法是什么?也许我离蟒蛇式思维太远了,所以请欣赏我的想法

我认为不可能像你在这里那样装饰属性。一个解决办法可能是这样

类项目:
定义初始化(自):
self.id=100
self.desc=“关于”的信息
self.title=“产品x”
self.vender\u ref=“af2k102hv813”
self.\uuuu呈现的属性\uuuu=[“描述”,“标题”]
def渲染_项目(i):
对于i.uu渲染的属性中的属性:
value=getattr(i,属性)
打印(“属性”,属性,=”,值)
i=项目()
第(i)项

我认为不可能像您在这里这样装饰属性。一个解决办法可能是这样

类项目:
定义初始化(自):
self.id=100
self.desc=“关于”的信息
self.title=“产品x”
self.vender\u ref=“af2k102hv813”
self.\uuuu呈现的属性\uuuu=[“描述”,“标题”]
def渲染_项目(i):
对于i.uu渲染的属性中的属性:
value=getattr(i,属性)
打印(“属性”,属性,=”,值)
i=项目()
第(i)项

您可以使用与上述内容类似的内容,并命名您希望以特定方式装饰的属性。但这可能有点极端。我认为这样更好,但我只是想提出另一个想法。也许可以改进一下

import inspect


class MyClass(object):
    at_a = '12'
    at_b = '34'

    def __init__(self):
        self.at_c = 'test'
        self.get_attr()

    def get_attr(self):
        attributes = inspect.getmembers(
            self, lambda a: not (inspect.isroutine(a))
        )
        attributes = [a for a in attributes if a[0].startswith('at_')]
        print(attributes)

    def myfunc(self):
        return self.at_a


test = MyClass()
这里是另一种方法,利用重新定义
\uuuu setattr\uuuu
方法。但是,此选项不适用于类属性:

class MyClass(object):
    a = '@render', '12'
    b = '34'

    def __init__(self):
        super().__setattr__('__rendered_attributes__', {})
        self.id = 100
        self.desc = '@render', "info about"
        self.title = "product x"
        self.vender_ref = "af2k102hv813"

    def myfunc(self):
        return self.a

    def __setattr__(self, key, value):
        if isinstance(value, tuple) and value[0] == '@render':
            self.__rendered_attributes__[key] = value[-1]
            value = value[-1]
        super().__setattr__(key, value)


test = MyClass()
print(test.__rendered_attributes__, test.a)

您可以使用类似于所描述的内容,并命名您希望以特定方式装饰的属性。但这可能有点极端。我认为这样更好,但我只是想提出另一个想法。也许可以改进一下

import inspect


class MyClass(object):
    at_a = '12'
    at_b = '34'

    def __init__(self):
        self.at_c = 'test'
        self.get_attr()

    def get_attr(self):
        attributes = inspect.getmembers(
            self, lambda a: not (inspect.isroutine(a))
        )
        attributes = [a for a in attributes if a[0].startswith('at_')]
        print(attributes)

    def myfunc(self):
        return self.at_a


test = MyClass()
这里是另一种方法,利用重新定义
\uuuu setattr\uuuu
方法。但是,此选项不适用于类属性:

class MyClass(object):
    a = '@render', '12'
    b = '34'

    def __init__(self):
        super().__setattr__('__rendered_attributes__', {})
        self.id = 100
        self.desc = '@render', "info about"
        self.title = "product x"
        self.vender_ref = "af2k102hv813"

    def myfunc(self):
        return self.a

    def __setattr__(self, key, value):
        if isinstance(value, tuple) and value[0] == '@render':
            self.__rendered_attributes__[key] = value[-1]
            value = value[-1]
        super().__setattr__(key, value)


test = MyClass()
print(test.__rendered_attributes__, test.a)

如果你说“属性”,你严格地说是属性,而不是方法,是吗?据我所知,你只能修饰方法,当然
properties
除外。如果你说“attributes”,你严格来说是指属性,而不是方法,是吗?据我所知,你只能装饰方法,当然
properties
除外。为什么<代码>渲染项适用于实现属性列表的任何类。OK,我看到了,渲染在类之外,它可能位于视图模板中为什么<代码>渲染项适用于实现属性列表的任何类。OK,我看到了,渲染在类之外,它可以位于视图模板中