是否可以重新定义括号[]使用哪个对象?
我可以继承list
对象,但是如何让解释器使用我的子类代替buildin列表对象?可能吗?
(我很确定我使用的是错误的条款 - 随意编辑)
>>> 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
>>>
我没有实际用途 - 只是好奇。
答案 0 :(得分:7)
括号是该语言的一部分。它们用于创建列表。重新定义它是不可能的(也不可取!)。
答案 1 :(得分: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'
答案 2 :(得分:0)
您可以尝试使用不使用ml替换列表
list = mlist()
但只是
list = mlist
(您可能在解释器中运行此问题,因为mlist()以递归方式调用list()等等。但是如果您将定义mlist的代码放在不同的范围内,例如在您导入的模块中,那么它会工作。)然后你可以通过
创建一个新的mlisttestlist = list()
但有趣的是,不是
testlist = []
我认为它在语法上是等价的。显然[]被硬编码来调用内置列表类型,而不是当前任何对象被命名为“list”。
答案 3 :(得分:0)
这是可能的。如果你愿意变得足够脏,那么大多数事情都可能在软件中出现。 :)当然,这是一个坏主意。如果您使用此类更改编写任何软件,则会出现许多问题:
这是2003年a CPython extension module(and example),与Python 2.3一起使用。它很可能需要更新才能与更新版本的Python一起使用,但它展示了您需要为这种特定方法获取多少脏东西。
另一种方法是在语法层面改变事物。 Logix为此方法提供了工具。这涉及较少的C黑客攻击,但引入了一个全新的解析器和编译器。