说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
众所周知,Python 列表使我们能够在一个封装下用不同的数据类型存储相似的数据特征。为了定制自己的列表数据结构,我们有可以用 UserList。这个类封装了列表对象。它是一个有用的基础类,对于你想自定义的类似列表的类,可以继承和覆盖现有的方法,也可以添加新的方法。这样我们可以对列表添加新的行为。它由 Python 内置 collections 模块提供。
正如在介绍 UserDict 时的情况,自定义类时我也不建议直接继承 list 基础类,而是使用 Python 内置 collections 模块提供 UserList。直接子类化内置类型(如 dict、list 或 str)容易出错,因为内置类型的方法通常会忽略用户覆盖的方法。不要子类化内置类型,用户自己定义的类应该继承 collections 模块中的类,例如 UserDict、UserList 和 UserString,这些类做了特殊设计,因此易于扩展。
具体可参考本教程 UserDict 中的说明。
下边我们实现一个自定义的列表类,在追加元素时值不能小于 10:
import collections
class MyList0(collections.UserList):
def append(self, item):
if item < 10:
raise ValueError(f'{item}小于10')
else:
super().append(item)
l = MyList0([1,2])
l
# [1, 2]
l.append(10)
l
# [1, 2, 10]
l.append(9)
# ...
# ValueError: 9小于10
这个实例的内容被保存为一个正常列表,通过 UserList 的 data 属性存取。实例内容被初始化为一个 list 的 copy,默认为 [] 空列表。 list 可以是迭代对象,比如一个Python列表,或者一个 UserList 对象。
l.data
# [1, 2, 10]
type(l)
# __main__.MyList0
type(l.data)
# list
要继承列表相关的功能不要使用内置的 list,应该使用 UserList,UserList 自身不是继承 list 而是 MutableSequence。这些问题只发生在 C 语言实现的内置类型内部的方法委托
上,但是为了让程序更加兼容有更好的执行效果,应该避免继承 list。在这方面 PyPy 的行为比 CPython 较好些。
UserDict、UserList 和 UserString 虽然没有内置类型的速度快,但是易于扩展。
更新时间:Oct. 9, 2021, 3:52 p.m. 标签:python list