如何在没有setattr的情况下清除实例数据?

时间:2012-06-12 20:31:06

标签: python json class

我希望在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 制作一个传递,但它会弄得一团糟。

2 个答案:

答案 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__(),在第一个之后创建新实例的所有后续调用都将返回首次创建的实例。