2013-10-25 32 views
0

这里真的很简单的问题。在ben创建之后,无论如何,我可以调用ben [0]来调用name和ben [1]来调用年龄吗?在Python中创建对象属性列表

我想知道是否有一种方法来作为列表访问这些属性。

class People(): 
    def __init__(self, name, age): 

ben=People("ben", "10") 
+0

这完全取决于你的类定义和init方法的其余部分所说的内容...... – Ben

+3

使用属性'ben.name'和'ben.age'更合乎逻辑。如果你坚持使用索引,你应该在类上实现['__getitem__'](http://docs.python.org/2/reference/datamodel.html#special-method-names)。 –

+0

// @本:很多10岁的孩子有数千个重点;不错的工作。 :) – abarnert

回答

4
class People(object):  
    def __init__(self,name,age): 
     self.stuff = [name,age] 
    def __getitem__(self, arg): 
     return self.stuff[arg] 

这里是

>>> b = People("ben",10) 
>>> b[0] 
'ben' 
>>> b[1] 
10 
>>> 

你也可以做类似

class People(object):  
    def __init__(self,name,age): 
     self.stuff = {'name':name,'age':age} 
    def __getitem__(self, arg): 
     return self.stuff[arg] 

b = People("asd",10) 
b['age'] 
b['name'] 
+0

这很整齐。 –

+0

酷,所以__getitem__创建一个列表? – stephan

+2

当你使用方括号来访问它时,不会调用__getitem__' ...'__init__'创建一个列表 –

5

这听起来像你试图建立一个namedtuple

>>> import collections 
>>> People = collections.namedtuple('People', 'name age') 
>>> ben = People("ben", 10) 
>>> ben.name 
'ben' 
>>> ben[0] 
'ben' 

如果你想在你的类的附加功能,而不是仅仅有属性,你可以从namedtuple继承,而不是直接使用它:

>>> class People(collections.namedtuple('People', 'name age')): 
...  def __str__(self): 
...   return self.name.title() + '!' 
>>> ben = People("ben", 10) 
>>> print(ben) 
Ben! 
>>> ben 
People(name='ben', age=10) 
>>> ben.name 
'ben' 
>>> ben[0] 
'ben' 
1

你想与你的类做什么是不可能的,因为它的属性没有固有的顺序,因为它们存储在一个字典中,所以没有合理的方法将ben[0]映射到ben.name而不是ben.age

但是你可以在几种不同的方式,使之合理修改类:

  • 选择一个订单并将其存储在一个列表中(例如,在一个类的属性)。然后,你的__getitem__只需拨打getattr(self, self._fields[index])
  • 选择一个您可以通过编程定义的订单(例如排序顺序)。
  • 使用元类使您的类在OrderedDict中存储其属性,在这种情况下,您在__init__中分配它们的顺序是它们的顺序。所以这只是self.__dict__.values()[index]。使用__slots__代替您的属性字典。

如果你看看源collections.namedtuple,你可以看到它使用这些方法的组合:有一个名为_fields存储字段名称类属性,而本场值存储在其继承的元组从,然后它将__dict__定义为@property,它们将它们放在一起即为OrderedDict。这可能比你想要的要聪明得多。而且,如果你需要这个聪明的,只是首先使用或继承namedtuple

相关问题