Python中类属性元组的简写方法

3 投票
2 回答
3551 浏览
提问于 2025-04-18 11:03

假设我正在使用一个Python包中的一个类,它的样子大概是这样的:

class foo(object):
    def __init__(self):
        self.a = None
        self.b = None
        self.c = None
        self.d = None
        self.e = None
        self.f = None

现在我需要在某个操作中使用这个类的对象foobar的属性bde,比如说调用一个函数qux:

print qux(foobar.b, foobar.d, foobar.e)

有没有什么办法可以简化这个过程,像下面这样想象中的代码:

print qux(*foobar.[b,d,e])

注意,这里有个限制:这个类和函数都不能被修改。

2 个回答

1

因为你不能修改这个类,那我们可以写一个函数,接收一个实例和任意多个属性名,然后返回一个元组。

class Foo(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3


def getitems(obj, *items):
    values = []

    for item in items:
        values.append(getattr(obj, item))

    return tuple(values)

f = Foo()
print getitems(f, 'a', 'c')  # prints (1, 3)
qux(*getitems(f, 'a', 'c'))

如果你愿意修改这个类的话,可以重写 __getitem__ 方法,让它接受一个键的元组。

class Foo(object):
    def __init__(self):
        self.a = 1
        self.b = 2
        self.c = 3

    def __getitem__(self, item):
        if isinstance(item, basestring):
            # treat single key as list of length one
            item = [item]

        values = []

        for key in item:
            # iterate through all keys in item
            values.append(getattr(self, key))

        return tuple(values)

f = Foo()
print f['a', 'c']  # prints (1, 3)
qux(*f['a', 'c'])
3

好吧,getattrsetattr 可以让你接近目标:

使用 setattr 进行赋值(这不是下一个操作所必需的,只是为了说明):

class foo(object):
    def __init__(self):
        for name in 'abcdef':
            setattr(self, name, None)

使用 getattr 获取值:

print qux(*(getattr(foobar, name) for name in 'bde'))

如果是普通的、较长的名字,你需要用 in ['foo', 'bar'] 来替代。

撰写回答