namedtuple是一个函数,其返回值的的行为很像tuple,若要使用它,需要从collections模块中引入,官方文档里说的清楚,namedtuple返回的是tuple的子类,与tuple的不同之处在于,它有属性字段,这使得它看起来,又很像类。下面是一段简单的示例代码
Point = namedtuple("Point", 'x, y')
# Point = namedtuple("Point", 'x y')
# Point = namedtuple("Point", ['x', 'y'])
p = Point(3, 4)
print(p.x, p.y) # 3, 4
print(issubclass(Point, tuple)) # True
Point的行为,非常像一个类,被注释掉的两行代码具有同样的效果。与普通类创建出来的对象相比,有一处明显不同,你不能修改x和y的值,代码p.x = 8 会引发异常。
初次见到这个类,感到非常的困惑,它和类相比,有什么优势么,既然已经有了类,何必再弄出namedtuple这个看起来不伦不类的东西呢!
我虽然知道,它的属性是不可更改的,但一直没有找到合适的应用场景,直到最近阅读pip的源码,恰好看到了namedtuple的使用。
pip源码里,设计了一个CommandInfo,定义如下
CommandInfo = namedtuple('CommandInfo', 'module_path, class_name, summary')
它是如何被使用的呢?当你在终端里输入pip命令,或者pip help命令时,pip会输出pip相关的所有子命令说明,这些信息,就是用CommandInfo来存储的
commands_dict = OrderedDict([
('install', CommandInfo(
'pip._internal.commands.install', 'InstallCommand',
'Install packages.',
)),
('download', CommandInfo(
'pip._internal.commands.download', 'DownloadCommand',
'Download packages.',
)),
...
('help', CommandInfo(
'pip._internal.commands.help', 'HelpCommand',
'Show help for commands.',
)),
OrderedDict可以保证按照定义时的顺序输出命令,CommandInfo是namedtuple创建的,它的三个属性module_path, class_name,summary都是不可更改的,使用namedtuple正好合适。
如果使用类,也可以描述并存储这些信息,但是普通类的属性可以被修改,定义一个属性不可被修改的类也并非不可以,但是那样就不如直接使用namedtuple。
这是我第一次见到的使用namedtuple的项目,在具体的案例场景里,的确可以有更深刻的体会。
QQ交流群: 211426309