2017-02-14 75 views
0

在python中,我需要在我的類,我可能serialize的屬性列表,這是麻煩的列出這些在類的頂部。相反,我想用同樣的方式@property裝飾器使用,這樣即東西:蟒蛇裝飾添加功能列表上的對象

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__被裝飾的對象類時建所以更新我不需要的評論在開始時出線。

問題是,當我編寫裝飾器時,我無法訪問類或對象,除非實際調用my_prop函數,因此我無法添加它。我做錯了嗎?有沒有更好的方法來做到這一點,或者可以做到這一點嗎?

如果這樣做可以請一些請展示我可以使用的裝飾器功能,否則如果有更好的方法,請給出一個例子。

謝謝。

回答

2

而不是建立一個列表,只需添加一個標記屬性到函數對象。然後枚舉具有該屬性的類上的所有函數。

因爲你在這裏property對象,你只能找到的財產​​對象的吸氣該屬性,所以你需要確保你訪問的類型,而不是實例的屬性,然後觸發單獨的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)} 

演示:

​​
+0

awsome的作品就像一個魅力! ...歡呼 – othane

0

你可以寫你的裝飾類外,有爭論的 「自我」 所對應的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 

然後初始化serialisables的列表中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 
[] 
+0

這正是我所在的地方,正是我想要避免的恐懼。 – othane

+0

@othane對不起,我誤解了。我認爲問題在於「我無法接觸到課堂或對象」,這是對「自我」的呼喚所解決的。再次閱讀後,我可以看到情況並非如此。 –