我希望在python中使用traversable(通过DB,单个文件或只是字符串)类。我写这个(简称):
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 / getattr 中为 keys / vals 制作一个传递,但它会弄得一团糟。
答案 0 :(得分: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天前遇到了这个问题。不知道这是不是你的问题,但你说的是“它就像我有一个单身人士”
答案 1 :(得分: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__()
,在第一个之后创建新实例的所有后续调用都将返回首次创建的实例。