我在Python中编写了一个容器类型,我正在尝试编写一个可靠的__repr__方法来正确处理容器包含自身的情况.
例如,这是内置的list功能:
>>> x = []
>>> x.append(x)
>>> repr(x)
'[[...]]'
Run Code Online (Sandbox Code Playgroud)
用C语言编写的用于CPython的容器类型可以通过使用Py_ReprEnter和实现此功能Py_ReprLeave.在纯Python中是否有相同的功能,还是我需要创建自己的?
你可以创建自己的,但是如果你想要正确地做到这一点有点痛苦:你不应该在对象本身上存储一个'被repr'd'标记,因为那不是线程安全的.相反,您可以存储正在重新创建的线程本地实例集.
更便宜的解决方案是依赖于内置repr的递归,例如:
def __init__(self, *list):
self._list= list
def __repr__(self):
return 'mything('+repr(self._list)[1:-1]+')')
Run Code Online (Sandbox Code Playgroud)
只要递归循环中的一个对象Py_ReprEnter发生,repr就不能形成完整的循环.
如何创建线程本地实例集?
使用线程模块:
class MyThing(object):
_local= threading.local()
_local.reprs= set()
def __repr__(self):
reprs= MyThing._local.reprs
sid= id(self)
if sid in reprs:
return 'MyThing(...)'
try:
reprs.add(sid)
return 'MyThing(%r)' % self.something
finally:
reprs.remove(sid)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1745 次 |
| 最近记录: |