0

我创建了一个类来包装一个值,以便我可以将其作为列表或普通值访问。但是,我只能将值表示为字符串或 int,而不是其本机类型。有一个更好的方法吗?

class Options(object):
    default_option = None

class Option(object):
    def __init__(self, name, value):
        self.name = name
        if isinstance(value, list):
            self.value = [] + value
        else:
            self.value = [ value ]

    def __str__(self): return self.value[-1]
    def __long__(self): return self.value[-1]
    def __int__(self): return self.value[-1]
    def __float__(self): return self.value[-1]        
    def __getitem__(self, index): return self.value[index]

setattr(Options, 'opt', Option('opt', None))
print Options.opt

产生输出:

'None'

但我不能进行这种类型的比较:

if Options.opt is None:

虽然这确实有效:

if Options.opt[0] is None:

if Options.opt != "some value":

if Options.opt == 1:

这样做的目的是让我不必去其他地方重构代码,这些代码可能将选项称为值而不是列表。可重复选项的引入将列表引入所有选项,因此需要一个包装器来允许访问值而无需将其作为列表进行访问。

4

1 回答 1

0

似乎如果没有覆盖is操作符的能力,这种变化会破坏现有的 API 调用。我将改为实现以下内容,它在维护现有 API 的同时实现对Options类的新 API 调用以获取list类型选项。

class ListOptions(object):
    pass

class Options(object):
    @classmethod
    def list(cls):
        return ListOptions

    @classmethod
    def __setattr__(cls, name, value):
        if instance(value, list):
            value = [] + value
        else:
            value = [ value ]
        object.__setattr__(cls, name, value[-1])
        setattr(ListOptions, name, value)

setattr(Options, 'opt', Option('opt', None))

现在,它像往常一样工作,返回列表中的最后一项(如果不是列表类型,则返回唯一的项):

if Options.opt is None:

而且,我可以通过访问器方法访问新list类型,list如下所示:

if Options.list().opt[0] is None:

if Options.list().opt != "some value":

if Options.list().opt == 1:

或者,通过 ListOptions 类:

if ListOptions.opt[0] is None:

if ListOptions.opt != "some value":

if ListOptions.opt == 1:

我想说这是 API 破坏和实现访问列表类型的显式方法之间的折衷。

于 2013-10-14T13:40:05.520 回答