处理属性的名称和值

时间:2012-12-20 18:12:14

标签: python attributes

我可能正在接近这个错误,但我会感激被理顺。

我希望能够同时使用类的某些属性的值和名称

样品:

class DoStuff(object):
    def __init__(self):
        self.a="Alpha"
        self.b="Beta"
        self.c="Gamma"
    def printStuff(self):
        for thing in [self.a, self.b, self.c]:
            print NAMEOFTHING, thing

我想要的是:

a Alpha
b Beta
c Gamma

我怎么能得到它?

编辑:有些混乱,因为我的例子显示我打印了所有值。相反,我想要这个:

a Alpha
c Gamma

我的打印方法列表中只包含'a'和'c'。

4 个答案:

答案 0 :(得分:8)

您的类和for循环的设置方式,没有什么可以代替NAMEOFTHING来获取这些变量的名称。以下是有关如何修改方法的一些备选方案:

  • 使用字典而不是单个属性,然后在for循环中提供密钥列表:

    class DoStuff(object):
        def __init__(self):
            self.names = {"a": "Alpha",
                          "b": "Beta",
                          "c": "Gamma"}
        def printStuff(self):
            for name in ['a', 'b', 'c']:
                print name, self.names[name]
    
  • 使用列表中的属性名称,然后使用getattr()

    class DoStuff(object):
        def __init__(self):
            self.a="Alpha"
            self.b="Beta"
            self.c="Gamma"
        def printStuff(self):
            for name in ['a', 'b', 'c']:
                print name, getattr(self, name)
    

答案 1 :(得分:5)

你最接近的是:

for thing in ['a', 'b', 'c']:
    print thing, getattr(self, thing)

变量可以有多个名称而且不知道自己的名字,所以如果你知道它是'a',那么你可以使用getattr来解析查找。

另一种选择(虽然与上述没有太大差别)

to_get = ['a', 'b', 'c']
from operator import attrgetter
blah = zip(to_get, attrgetter(*to_get)(self))

答案 2 :(得分:1)

根据Jon的回答,您可能还会发现将要包含在输出中的属性列表设置为可选参数会很有帮助:

def printStuff(self, included=['a', 'c']):
    for thing in included:
        print thing, getattr(self, thing)

通过说DoStuff().printStuff()只获取acDoStuff().printStuff(['a', 'b', 'c'])的值,可以轻松生成两个输出得到这三个。当然,这个允许来改变输出 - 如果它是一个明确的设计目标,那么打印的字段集是不变的,这会适得其反。

答案 3 :(得分:0)

# You can use __dict__
>>> class x:
>>>     def __init__(self):
>>>         self.a = 1
>>>         self.b = 2
>>>         self.c = 3
>>>         self.d = 4

>>>     def prnt(self):
>>>         limit = "b", "c"
>>>         return {k:v for (k, v) in self.__dict__.iteritems()if k in limit}

>>> r = x()
>>> print r.prnt()
    {'b': 2, 'c': 3}

# __dict__ can be also done outside the class

limit = "b", "c"
print {k:v for (k, v) in r.__dict__.iteritems()if k in limit}