简体   繁体   中英

Creating a list out of object attributes in Python

Really simple question here. After ben is created, is there anyway I can call ben[0] to call name and ben[1] to call age?

i'm wondering if there is a way to access these attributes as a list.

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

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

It sounds like you're trying to build a namedtuple :

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

If you want additional functionality in your class beyond just having attributes, you can just inherit from the namedtuple instead of using it directly:

>>> 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'
class People(object):     
    def __init__(self,name,age):
        self.stuff = [name,age]
    def __getitem__(self, arg):
        return self.stuff[arg]

and here it is

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

you could also do something like

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']

What you want to do with your class is impossible, because its attributes have no inherent order, because they're stored in a dict, so there is no reasonable way to map ben[0] to ben.name instead of to ben.age .

But you can modify the class in a few different ways to make it reasonable:

  • Pick an order and store it in a list (eg, in a class attribute). Then, your __getitem__ just calls getattr(self, self._fields[index]) .
  • Pick an order that you can define programmatically (eg, sorted order).
  • Use a metaclass to make your class store its attributes in an OrderedDict , in which case the order in which you assign them in __init__ is their order. So it's just self.__dict__.values()[index] .
  • Use __slots__ instead of a dict for your attributes.

If you look at the source for collections.namedtuple , you can see that it's using a combination of these: there's a class attribute named _fields to store the field names, while the field values are stored in the tuple that it inherits from, and it then defines __dict__ as a @property that puts them together an OrderedDict on the fly. This is probably far more clever than you need to be. And, if you do need to be this clever, just use or inherit from a namedtuple in the first place.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM