python装饰器将函数添加到对象上的列表中
在python中,我需要在我的类上创建一个属性列表,我可以序列化这些属性,在类的顶部列出这些属性是很麻烦的。相反,我希望以使用@property的相同方式使用decorator,例如:python装饰器将函数添加到对象上的列表中,python,python-decorators,Python,Python Decorators,在python中,我需要在我的类上创建一个属性列表,我可以序列化这些属性,在类的顶部列出这些属性是很麻烦的。相反,我希望以使用@property的相同方式使用decorator,例如: class MyClass(object): # I dont like having to do this for example #__list_of_props_to_serialise__ = ['my_prop',] @property @serialise
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__}
其中,构建类时,decorator会更新对象上的\u props\u to\u serialise\uuu的列表,因此我不需要在开始时注释掉的行
问题是,当我开始编写decorator时,在实际调用my_prop
函数之前,我无法访问该类或对象,因此无法添加它。我是否“做错了”,是否有更好的方法来做这件事,或者是否可以通过某种方式来做
如果可以做到这一点,请显示一些装饰功能,我可以使用,否则,如果有更好的方法,请给出一个例子
谢谢。只需向函数对象添加标记属性,而不是建立列表。然后枚举类上具有该属性的所有函数
因为这里有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)}
演示:
不必建立列表,只需向函数对象添加标记属性即可。然后枚举类上具有该属性的所有函数
因为这里有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)}
演示:
您可以在类之外编写decorator,使用与MyClass类型对象相对应的参数“self”:
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中初始化序列化文件列表:
class MyClass(object):
def __init__(self):
self.serialisables = []
@property
@serialise
def my_prop(self):
return "this is my property"
使用该属性时,其名称将添加到serialisables属性中:
>>> c = MyClass()
>>> c.my_prop
Adding my_prop
this is my property
>>> c.serialisables
['my_prop']
但是,只有在使用c.my_prop时,才会添加属性的名称:
>>> c = MyClass()
>>> c.serialisables
[]
您可以在类之外编写decorator,使用与MyClass类型对象相对应的参数“self”:
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中初始化序列化文件列表:
class MyClass(object):
def __init__(self):
self.serialisables = []
@property
@serialise
def my_prop(self):
return "this is my property"
使用该属性时,其名称将添加到serialisables属性中:
>>> c = MyClass()
>>> c.my_prop
Adding my_prop
this is my property
>>> c.serialisables
['my_prop']
但是,只有在使用c.my_prop时,才会添加属性的名称:
>>> c = MyClass()
>>> c.serialisables
[]
这正是我所处的位置,也正是我想避免的地方。@othane对不起,我误解了。我认为问题在于“我没有访问类或对象的权限”,调用“self”解决了这个问题。再读一遍后,我发现情况并非如此。这正是我所处的位置,也正是我试图避免的地方。恐怕。@othane我很抱歉我误解了。我认为问题在于“我没有访问类或对象的权限”,调用“self”解决了这个问题。再读一遍,我发现情况并非如此。