简体   繁体   English

在Python中根据对象属性创建列表

[英]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? 创建了ben之后,是否仍然可以调用ben [0]来调用名称,并调用ben [1]来调用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 : 听起来您正在尝试构建一个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: 如果您除了拥有属性之外,还希望类中具有其他功能,则可以从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'
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 . 您想要对类进行的操作是不可能的,因为其属性没有固有的顺序,因为它们存储在dict中,因此没有合理的方法将ben[0]映射到ben.name而不是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). 选择一个订单并将其存储在列表中(例如,在class属性中)。 Then, your __getitem__ just calls getattr(self, self._fields[index]) . 然后,您的__getitem__只是调用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. 使用元类使您的类将其属性存储在OrderedDict ,在这种情况下,您在__init__分配它们的顺序就是它们的顺序。 So it's just self.__dict__.values()[index] . 所以这只是self.__dict__.values()[index]
  • Use __slots__ instead of a dict for your attributes. 使用__slots__代替dict作为属性。

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. 如果您查看collections.namedtuple的源代码,您会发现它使用了以下两种方法的组合:有一个名为_fields的类属性用于存储字段名称,而字段值则存储在其继承的元组中,并且然后将__dict__定义为@property ,将它们动态组合在一起形成OrderedDict 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. 而且,如果您确实需要变得聪明,则首先使用或从namedtuple继承。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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