gpt4 book ai didi

python - 有没有办法用 collections.namedtuple 支持弱引用?

转载 作者:行者123 更新时间:2023-12-03 19:23:45 24 4
gpt4 key购买 nike

我想使用对命名元组的弱引用,但它失败了:

>>> import collections
>>> import weakref
>>>
>>> Foo = collections.namedtuple('Foo','a b c')
>>> weakref.ref(Foo(1,2,3))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create weak reference to 'Foo' object

我试图用 __slots__ = ('__weakref__',) 解决这个问题但这也失败了:
>>> class Foo(collections.namedtuple('Foo','a b c')):
... __slots__ = ('__weakref__',)
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
nonempty __slots__ not supported for subtype of 'Foo'

有解决方法吗?

最佳答案

简答

不幸的是,非空 __slots__ flat-out 不适用于任何类型的元组,而不仅仅是 namedtuple()。

解决

你能做的最好的事情就是拥有一个不从元组继承的类。

我为你写了一篇(见下文)。它是这样使用的:

from __future__ import print_function
from altnamedtuple import AltNamedTuple
from weakref import proxy

class Point(AltNamedTuple):
__slots__ = ('x', 'y', '__weakref__')
def __init__(self, x, y):
self.x = x
self.y = y

# Now, exercise the capabilities of the named tuple alternative
p = Point(10, 20)
r = proxy(p)
print(len(r)) # sizeable
print(r[0]) # indexed access
print(r.y) # attribute access
print(list(r)) # iterable
x, y = r # unpackable
print(x, y)
print(20 in r) # membership testing
print(tuple(reversed(p))) # reversible
print(r == (10, 20)) # equality
print(r != (30, 40)) # inequality
print(hash(p)) # hashable
print(r) # nice repr
print(r._asdict()) # conversion to a dict
print(r._replace(y=2))
t = (11, 22)
print(r.count(10))
print(r.index(20))
print(Point._make(t)) # alternative constructor

请注意,weakrefs 代理不会传递对 __hash__ 或 __reversed__ 的调用。这是任何类都无法解决的内在限制。

AltNamedTuple 的源代码

这是完成所有工作的类:
class AltNamedTuple(object):
"Subclasser needs to define: __slots__ and __init__"
__slots__ = ()
def __getattr__(self, attr):
if attr != '_fields': raise AttributeError(attr)
if '__weakref__' in self.__slots__:
return self.__slots__[:-1]
return self.__slots__
def __len__(self):
return len(self._fields)
def __getitem__(self, index):
attr = self._fields[index]
return getattr(self, attr)
def __iter__(self):
for attr in self._fields:
yield getattr(self, attr)
def __reversed__(self):
return iter(reversed(tuple(self)))
def __eq__(self, other):
return tuple(self) == tuple(other)
def __ne__(self, other):
return tuple(self) != tuple(other)
def __hash__(self):
return hash(tuple(self))
def __repr__(self):
pairs = ['%s=%r' % (a, getattr(self, a)) for a in self._fields]
return ('%s(%s)' % (self.__class__.__name__, ', '.join(pairs)))
@classmethod
def _make(cls, iterable):
return cls(*iterable)
def _asdict(self):
return dict(zip(self._fields, self))
def _replace(_self, **kwds):
d = _self._asdict()
d.update(kwds)
return _self.__class__(**d)
def count(self, value):
return tuple(self).count(value)
def index(self, value):
return tuple(self).index(value)

关于python - 有没有办法用 collections.namedtuple 支持弱引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58312618/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com