Python中拦截切片操作
我想模仿一个普通的 python 列表,除了每当通过切片添加或删除元素时,我想“保存”列表。 这可能吗? 这是我的尝试,但它永远不会打印“保存”。
class InterceptedList(list):
def addSave(func):
def newfunc(self, *args):
func(self, *args)
print 'saving'
return newfunc
__setslice__ = addSave(list.__setslice__)
__delslice__ = addSave(list.__delslice__)
>>> l = InterceptedList()
>>> l.extend([1,2,3,4])
>>> l
[1, 2, 3, 4]
>>> l[3:] = [5] # note: 'saving' is not printed
>>> l
[1, 2, 3, 5]
这确实适用于其他方法,例如 append
和 extend
,但不适用于切片操作。
编辑:真正的问题是我使用的是 Jython 而不是 Python 并且忘记了它。 对问题的评论是正确的。 这段代码在 Python (2.6) 中运行良好。 但是,代码和答案在 Jython 中都有效。
I want to imitate a normal python list, except whenever elements are added or removed via slicing, I want to 'save' the list. Is this possible? This was my attempt but it will never print 'saving'.
class InterceptedList(list):
def addSave(func):
def newfunc(self, *args):
func(self, *args)
print 'saving'
return newfunc
__setslice__ = addSave(list.__setslice__)
__delslice__ = addSave(list.__delslice__)
>>> l = InterceptedList()
>>> l.extend([1,2,3,4])
>>> l
[1, 2, 3, 4]
>>> l[3:] = [5] # note: 'saving' is not printed
>>> l
[1, 2, 3, 5]
This does work for other methods like append
and extend
, just not for the slice operations.
EDIT: The real problem is I'm using Jython and not Python and forgot it. The comments on the question are correct. This code does work fine in Python (2.6). However, the code nor the answers work in Jython.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
来自 Python 3 文档:
From the Python 3 docs:
这已经够猜测了。 让我们开始使用事实吧?
据我所知,底线是您必须重写这两组方法。
如果你想实现撤消/重做,你可能应该尝试使用撤消堆栈和一组可以 do()/undo() 本身的操作。
代码
Jython 2.5
Python 2.6.2
That's enough speculation. Let's start using facts instead shall we?
As far as I can tell, the bottom line is that you must override both set of methods.
If you want to implement undo/redo you probably should try using undo stack and set of actions that can do()/undo() themselves.
Code
Jython 2.5
Python 2.6.2
“setslice”和“delslice”已被弃用,如果你想进行拦截,你需要使用传递给“setitem”和“delitem”的Python切片对象。 如果您想拦截切片和普通访问,则此代码在 python 2.6.2 中完美运行。
"setslice" and "delslice" are deprecated, if you want to do the interception you need to work with python slice objects passed to "setitem" and "delitem". If you want to intecept both slices and ordinary accesses this code works perfectly in python 2.6.2.
调用
__getslice__
和__setslice__
的情况非常有限。 具体来说,切片仅在您使用常规切片时发生,其中第一个元素和结束元素仅被提及一次。 对于任何其他切片语法,或者根本没有切片,将调用__getitem__
或__setitem__
。the circumstances where
__getslice__
and__setslice__
are called are pretty narrow. Specifically, slicing only occurs when you use a regular slice, where the first and end elements are mentioned exactly once. for any other slice syntax, or no slices at all,__getitem__
or__setitem__
is called.