如有一些学生信息字段,字段是固定的,(姓名,年龄,性别,邮箱),我们选择用元组保存
姓名 | 年龄 | 性别 | 邮箱 |
---|---|---|---|
jime | 15 | 男 | 122@qq.com |
tom | 13 | 男 | 123@qq.com |
使用如下数据结构保存:
(‘jim’,15,‘male’,‘122@qq.com’)
(‘tom’,13,‘male’,‘123@qq.com’)
存在的问题:
def xxx_func(student):
# 获取年龄小于18的
if student[1] < 18:
pass
# 根据性别返回男性
if student[2] == 'male':
pass
student = ('tom',13,'male','123@qq.com')
xxx_func(student)
我们需要根据元组中的排序顺序依次去根据索引来编码,如果字段比较多的情况看下,student[2] 代表什么含义,我们可能需要回过头去数一下对应位置才能知道含义,所以对于编程者和后期维护或者阅读代码的人来讲将是灾难性的;
目前的解决方案的思路:
- 自定定义常量
- 根据python标准库中collections 中提供的namedtuple代替内置的tuple
一、自定义常量
1、通过自己赋值的方式
student = ('tom',13,'male','123@qq.com')
NAME,AGE,SEX,EMAIL = range(len(student))
# 如果我想输出e-mail这个学生的e-mail
print(student[EMAIL])
123@qq.com
-
这种方式是自己定义一堆常量,但是也存在一定的问题,如下面的数据结构:
- 学生:(‘tom’,13,‘male’,‘123@qq.com’)
-
老师:(33,‘Max’)姓名,年龄,性别,邮箱
-
年龄,姓名
那么根据上面第一种方式,我们需要对老师和学生分别维护不同的常量,以姓名为例:
- 学生 STU_NAME = 0
- 老师 TEA_NAME = 1
很可能有些字段的位置还是一样的,所以就存在一定的冗余和麻烦,所以下面一种方式可以有效的解决,就是用枚举;
2、使用枚举的方式
from enum import IntEnum
# 从标准库中导入整型的枚举
# 再创建各自的一个类集成这个整型枚举
class StuEnum(IntEnum):
NAME = 0,
AGE = 1,
SEX = 2,
EMAIL = 3
class TeaEnum(IntEnum):
AGE = 0,
NAME = 1,
student = ('tom',13,'male','123@qq.com')
teacher = (34, 'max')
#获取学生的姓名
print(student[StuEnum.NAME])
print(teacher[TeaEnum.NAME])
tom
max
二、使用namedtuple
from collections import namedtuple
#给这个tuple起个 Student的名称,第二个参数就是定义各个位置的别名
stu = namedtuple("Student", ['name', 'age', 'sex', 'email'])
# 实例化这个元组,
s2 = stu('tom', 13, 'male', '123@qq.com')
print(stu.__name__) # 输出这个元组的名称
print(isinstance(stu, tuple)) # 新创建出的这个s2 其实就是一个tuple,
print(s2[0]) # 我们可以按照元组索引的方式去取值
print(s2[1])
print(s2.name) # 当然我们更希望通过别名直接去取值
print(s2.age)
通过可以命名的元组,我们可以根据自己的需求直接去取值,这样从代码的可读性上看就好多了,同时元组存储数据时,它所占的内存空间更少;