1

我想在python中制作可遍历的(通过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的通行证,但它会弄得一团糟。

4

2 回答 2

0

您的__separator____keys____vals____slots__对象“存储”(类对象)的属性。我不知道它是否完全相同,但我称之为类的静态变量。

如果您想为每个 Storage 实例设置不同的值,请在__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天前遇到了这个问题。不知道这是否正是你的问题,但你说过“就像我有一个单身人士”

于 2012-06-12T20:57:08.857 回答
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__()子类中覆盖,在第一个实例之后创建新实例的所有后续调用都将返回第一个创建的实例。

于 2012-06-12T21:33:47.510 回答