重定义Python内置数据类型
可以重新定义方括号 [] 使用哪个对象吗?
我可以创建一个列表的子类,但我该如何让解释器使用我的子类,而不是内置的列表对象呢?这可能吗?
(我觉得我用的术语可能不太对,欢迎修改)
>>> class mlist(list):
... def __init__(self):
... list.__init__(self)
... def __getitem__(self, item):
... return list.__getitem__(self, item) * 2
...
>>> testlist = mlist()
>>> testlist.append(21)
>>> testlist[0]
42
>>> list = mlist() # maybe setting the 'list' type will do it?
>>> testlist = []
>>> testlist.append(21)
>>> testlist[0]
21 # Nope
>>>
我并没有实际的用途,只是好奇而已。
4 个回答
0
你可以用 not 来把 list 替换成 mlist,就像你尝试的那样,
list = mlist()
但其实只需要
list = mlist
(你在解释器中运行这个可能会遇到问题,因为 mlist() 会递归地调用 list() 等等。不过,如果你把定义 mlist 的代码放在一个不同的范围,比如在你导入的模块里,那就没问题了。)然后你可以通过
testlist = list()
来创建一个新的 mlist,
testlist = []
但有趣的是,不能通过
我原以为这两者在语法上是等价的。显然,方括号 [ ] 是硬编码的,用来调用内置的 list 类型,而不是当前名为 "list" 的任何对象。
7
这些括号是编程语言的一部分。它们用来创建列表。我们不能重新定义它们的用法(而且也没有必要这样做!)。
2
试着在你运行了你发的代码之后再运行这段代码
>>> testlist = list()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'mlist' object is not callable
现在,使用我发的代码来确定类型
>>> type([])
<type 'list'>
>>> type(list)
<class '__main__.mlist'>
>>> type(testlist)
<type 'list'>
看起来 []
创建的是 list
,而不是 mlist
,这看起来有点奇怪 :S
更新
我用 dis
检查了生成的字节码,下面的代码被生成了
>>> import dis # python's disassembler
>>> def code1():
... return []
...
>>> dis.dis(code1)
2 0 BUILD_LIST 0
3 RETURN_VALUE
>>> def code2():
... return list()
...
>>> dis.dis(code2)
2 0 LOAD_GLOBAL 0 (list)
3 CALL_FUNCTION 0
6 RETURN_VALUE
看起来 list
会调用分配给它的任何东西,而 []
会被转换成 BUILD_LIST
字节码。似乎 []
并不是被翻译成 list
,因此 []
的行为就是创建列表。
更新 2
Python 类是可以更新的
>>> class NewList(list):
... pass
...
>>> a = NewList()
>>> a.append(23)
>>> a[0]
23
>>> def double_getitem(self, key):
... return list.__getitem__(self, key) * 2
...
>>> NewList.__getitem__ = double_getitem
>>> a[0]
46
不过,内置类,比如 list,除外
>>> list.__getitem__ = double_getitem
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'list'