bri*_*ice 5 python ctypes introspection
我想修补Python列表,特别是__setitem__用自定义代码替换方法.请注意,我不是要扩展,而是覆盖内置类型.例如:
>>> # Monkey Patch
... # Replace list.__setitem__ with a Noop
...
>>> myList = [1,2,3,4,5]
>>> myList[0] = "Nope"
>>> myList
[1, 2, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
是的,我知道这对python代码来说是一个彻头彻尾的变态.不,我的用例并没有多大意义.尽管如此,它能做到吗?
forbiddenfruit模块允许修补C内置,但在尝试覆盖列表方法时不起作用我实际上设法覆盖了方法本身,如下所示:
import ctypes
def magic_get_dict(o):
# find address of dict whose offset is stored in the type
dict_addr = id(o) + type(o).__dictoffset__
# retrieve the dict object itself
dict_ptr = ctypes.cast(dict_addr, ctypes.POINTER(ctypes.py_object))
return dict_ptr.contents.value
def magic_flush_mro_cache():
ctypes.PyDLL(None).PyType_Modified(ctypes.cast(id(object), ctypes.py_object))
print(list.__setitem__)
dct = magic_get_dict(list)
dct['__setitem__'] = lambda s, k, v: s
magic_flush_mro_cache()
print(list.__setitem__)
x = [1,2,3,4,5]
print(x.__setitem__)
x.__setitem__(0,10)
x[1] = 20
print(x)
Run Code Online (Sandbox Code Playgroud)
其中输出如下:
? python3 override.py
<slot wrapper '__setitem__' of 'list' objects>
<function <lambda> at 0x10de43f28>
<bound method <lambda> of [1, 2, 3, 4, 5]>
[1, 20, 3, 4, 5]
Run Code Online (Sandbox Code Playgroud)
但是如输出中所示,这似乎不会影响设置项目的正常语法(x[0] = 0)
作为一个较小的选择,如果我能够修补单个列表的实例,这也可以工作.也许通过将列表的类指针更改为自定义类.
| 归档时间: |
|
| 查看次数: |
626 次 |
| 最近记录: |