仅将装饰器应用于 class 属性
apply decorator to a class attribute only
不确定是否可行,但我想在 python class 中复制来自 java 的 @annotations 的想法。目标是使用自定义装饰器(例如@render)遍历此 class 和 return 中的所有属性 "marked"。因此,在这种情况下,我可以定义一个通用函数来呈现通用 UI/view 模板以仅显示来自任何 class.
的呈现属性
在这个假想的代码中,项目 class 将是:
class Item:
def __init__(self):
self.id = 100
@render
self.desc = 'info about'
@render
self.title = 'product x'
self.vender_ref = 'af2k102hv813'
并且只有 title 和 desc 会是 shown/returned。实现此功能的方法是什么?可能我离 pythonic 的想法太远了,所以感谢任何想法。
我认为不可能像您在这里那样装饰属性。一种解决方案可能是这样。
class Item:
def __init__(self):
self.id = 100
self.desc = "info about"
self.title = "product x"
self.vender_ref = "af2k102hv813"
self.__rendered_attributes__ = ["desc", "title"]
def render_item(i):
for attribute in i.__rendered_attributes__:
value = getattr(i, attribute)
print("attr", attribute, "=", value)
i = Item()
render_item(i)
您可以使用与描述的类似的东西 in this answer and name your attributes that you want to decorate in a specific way. This may be a bit extreme though. I think 更好,但我只是想提出另一个想法。也许可以改进。
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()
还有一种方法,利用重新定义__setattr__
方法。不过这个不适用于 class 属性:
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)
不确定是否可行,但我想在 python class 中复制来自 java 的 @annotations 的想法。目标是使用自定义装饰器(例如@render)遍历此 class 和 return 中的所有属性 "marked"。因此,在这种情况下,我可以定义一个通用函数来呈现通用 UI/view 模板以仅显示来自任何 class.
的呈现属性在这个假想的代码中,项目 class 将是:
class Item:
def __init__(self):
self.id = 100
@render
self.desc = 'info about'
@render
self.title = 'product x'
self.vender_ref = 'af2k102hv813'
并且只有 title 和 desc 会是 shown/returned。实现此功能的方法是什么?可能我离 pythonic 的想法太远了,所以感谢任何想法。
我认为不可能像您在这里那样装饰属性。一种解决方案可能是这样。
class Item:
def __init__(self):
self.id = 100
self.desc = "info about"
self.title = "product x"
self.vender_ref = "af2k102hv813"
self.__rendered_attributes__ = ["desc", "title"]
def render_item(i):
for attribute in i.__rendered_attributes__:
value = getattr(i, attribute)
print("attr", attribute, "=", value)
i = Item()
render_item(i)
您可以使用与描述的类似的东西 in this answer and name your attributes that you want to decorate in a specific way. This may be a bit extreme though. I think
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()
还有一种方法,利用重新定义__setattr__
方法。不过这个不适用于 class 属性:
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)