2012-06-12 40 views
1

我希望能夠在python中遍歷(通過DB,單個文件或只是字符串)類。我寫這篇文章(短路):如何清除沒有setattr的實例數據?

from json import JSONDecoder, JSONEncoder 
def json_decode(object): return JSONDecoder().decode(object) 
def json_encode(object): return JSONEncoder().encode(object) 

class Storage: 
__separator__ = 'ANY OF ANYS' 
__keys__ = [] 
__vals__ = [] 
__slots__ = ('__keys__', '__vals__', '__separator__') 

def __getattr__(self, key): 
    try: 
     return self.__vals__[self.__keys__.index(key)] 
    except IndexError: 
     raise AttributeError 

def __setattr__(self, key, val): 
    self.__keys__.append(key) 
    self.__vals__.append(val) 

def store(self): 
    return (json_encode(self.__keys__) + self.__separator__ + 
      json_encode(self.__vals__)) 

def restore(self, stored): 
    stored = stored.split(self.__separator__) 
    for (key, val) in zip(json_decode(stored[0]), json_decode(stored[1])): 
     setattr(self, key, val) 

而雅 - 這項工作,但是...當我使更多的情況下,所有的人都喜歡單身。

所以 - 如何設置屬性爲實例沒有_ setattr _?

PS。我有個主意 - set/getattrkeys/vals,但它會弄得一團糟。

回答

0

您的__separator__,__keys__,__vals____slots__是對象「存儲」(類對象)的屬性。我不知道它是否完全一樣,但我會稱之爲類的靜態變量。

如果您想爲存儲的每個實例不同的值,在你的__init__函數定義每個變量:

class Storage(object): 
    __slots__ = ('__keys__', '__vals__', '__separator__') 
    def __init__(self): 
     super(Storage, self).__setattr__('__separator__', "ANY OF ANYS") 
     super(Storage, self).__setattr__('__keys__', []) 
     super(Storage, self).__setattr__('__vals__', []) 

    def __getattr__(self, key): 
     try: 
      vals = getattr(self, '__vals__') 
      keys = getattr(self, '__keys__') 
      return vals[keys.index(key)] 
     except IndexError: 
      raise AttributeError 

    def __setattr__(self, key, val): 
     vals = getattr(self, '__vals__') 
     keys = getattr(self, '__keys__') 
     vals.append(val) 
     keys.append(key) 

編輯,以便GETATTR和SETATTR工作

我得到了這個問題2天前。不知道如果這正是你的問題,但你說的是關於「它像我有一個單身」

+0

__slots__用於保存內存(谷歌它) self.xxx將被__setattr__解析,所以這不是我想要的。 –

+0

然後離開'__slots__'就像以前一樣。但是如果你沒有爲每個實例上的'__keys__'和'__vals__'設置一個不同的[]'(像我建議的那樣),你將在我試過的所有實例 – AlbertFerras

+0

中共享相同的列表。 '__getattr__'。當我想'self .__ key/vals__'時,我得到了最大的recurence深層錯誤 - '__key/vals__'中的'__getattr__'操作符。 –

0

你可以讓你的Storage類特殊的基類的這樣的一個子類:

class Singleton(object): 
    def __new__(cls, *args, **kwargs): 
     if '_inst_' not in vars(cls): 
      cls._inst = type.__new__(cls, *args, *kwargs) 
     return cls._inst 

class Storage(Singleton): 
    .... 

只要你不在你的子類中覆蓋__new__(),所有後續調用在第一個之後創建新實例將返回第一個創建的實例。