如何使 Python class 属性可通过索引访问?
How to make a Python class properties accesible by index?
我有一个像这样的 Django 模型:
class Competitor(models.Model):
"""
Competitor model object
"""
name = models.CharField(max_length=20)
easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
并且我希望能够通过索引访问属性,因此,如果我写 competitor[0]
,它应该 return name
的值。
我看过了,根据 this 的问题,我必须“同时实施 __iter__()
和 __getitem__()
等方法。”但是我不知道在这个方法里面做什么。
有人知道怎么做吗?
如果您只打算获取物品,则必须覆盖 __getitem__
。
class Competitor(models.Model):
"""
Competitor model object
"""
name = models.CharField(max_length=20)
easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
def __getitem__(self, key):
if key == 0:
return self.nome
elif key == 1:
return self.easy
...
elif key == 8:
return self.replica
一种简单的方法是使用列表跟踪属性:
class Competitor(models.Model):
"""
Competitor model object
"""
name = models.CharField(max_length=20)
easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
_list = [name, easy, hard, tematicas, random_score, min1, min2, deluxe, replica]
def __getitem__(self, key):
return self._list[key]
为了完全实现下标符号 ([]
),您还需要实现 __setitem__
和 __delitem__
。
def __setitem__(self, index, value):
self._list[index] = value
我不知道你是否可以在不映射每个索引的情况下做到这一点。 Buf 如果您可以确保索引的顺序将始终相同,这对您有用:
class Competitor:
def __init__(self):
self.name = 'Leonardo'
def __getitem__(self, key):
if key == 0:
return self.name
if __name__ == "__main__":
print(Competitor()[0]) # Leonardo
首先感谢@julianofischer 的回答。它教会了我如何实现我将在这个答案中实现的方法。
首先添加一个字符串列表,其中包含您希望能够使用 []
访问的字段名称作为 class 的属性,如下所示:
class Competitor(Model):
"""
Competitor model object
"""
name = CharField(max_length=20)
easy = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
_list = [ 'easy', 'hard', 'tematicas', 'random_score', 'min1', 'min2', 'deluxe', 'replica' ]
然后,如果您希望同时获取和设置值,则必须实现 __getitem__
和 __setitem__
,如下所示:
def __getitem__(self, index: int):
return self.__dict__[self._list[index]]
def __setitem__(self, index: int, value: list):
self.__dict__[self._list[index]] = value
self.save(update_fields=[self._list[index]])
这样,您可以使用 __getitem__
访问字段的值,使用 .__dict__[index]
并返回这些值,而使用 __setitem__
,您可以直接修改这些值。
我有一个像这样的 Django 模型:
class Competitor(models.Model):
"""
Competitor model object
"""
name = models.CharField(max_length=20)
easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
并且我希望能够通过索引访问属性,因此,如果我写 competitor[0]
,它应该 return name
的值。
我看过了,根据 this 的问题,我必须“同时实施 __iter__()
和 __getitem__()
等方法。”但是我不知道在这个方法里面做什么。
有人知道怎么做吗?
如果您只打算获取物品,则必须覆盖 __getitem__
。
class Competitor(models.Model):
"""
Competitor model object
"""
name = models.CharField(max_length=20)
easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
def __getitem__(self, key):
if key == 0:
return self.nome
elif key == 1:
return self.easy
...
elif key == 8:
return self.replica
一种简单的方法是使用列表跟踪属性:
class Competitor(models.Model):
"""
Competitor model object
"""
name = models.CharField(max_length=20)
easy = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(models.PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(models.PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(models.PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
_list = [name, easy, hard, tematicas, random_score, min1, min2, deluxe, replica]
def __getitem__(self, key):
return self._list[key]
为了完全实现下标符号 ([]
),您还需要实现 __setitem__
和 __delitem__
。
def __setitem__(self, index, value):
self._list[index] = value
我不知道你是否可以在不映射每个索引的情况下做到这一点。 Buf 如果您可以确保索引的顺序将始终相同,这对您有用:
class Competitor:
def __init__(self):
self.name = 'Leonardo'
def __getitem__(self, key):
if key == 0:
return self.name
if __name__ == "__main__":
print(Competitor()[0]) # Leonardo
首先感谢@julianofischer 的回答。它教会了我如何实现我将在这个答案中实现的方法。
首先添加一个字符串列表,其中包含您希望能够使用 []
访问的字段名称作为 class 的属性,如下所示:
class Competitor(Model):
"""
Competitor model object
"""
name = CharField(max_length=20)
easy = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Easy Mode')
hard = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Hard Mode')
tematicas = ArrayField(PositiveSmallIntegerField(), size=7, null=True, blank=True, verbose_name='Tematicas')
random_score = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Random Mode')
min1 = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 1')
min2 = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='minuto 2')
deluxe = ArrayField(PositiveSmallIntegerField(), size=14, null=True, blank=True, verbose_name='Deluxe')
replica = ArrayField(PositiveSmallIntegerField(), size=9, null=True, blank=True, verbose_name='Replica')
_list = [ 'easy', 'hard', 'tematicas', 'random_score', 'min1', 'min2', 'deluxe', 'replica' ]
然后,如果您希望同时获取和设置值,则必须实现 __getitem__
和 __setitem__
,如下所示:
def __getitem__(self, index: int):
return self.__dict__[self._list[index]]
def __setitem__(self, index: int, value: list):
self.__dict__[self._list[index]] = value
self.save(update_fields=[self._list[index]])
这样,您可以使用 __getitem__
访问字段的值,使用 .__dict__[index]
并返回这些值,而使用 __setitem__
,您可以直接修改这些值。