gpt4 book ai didi

python - 添加新实例变量的 Python set 类子类化的正确(或最佳)方法是什么?

转载 作者:太空狗 更新时间:2023-10-29 17:38:40 25 4
gpt4 key购买 nike

我正在实现一个几乎与集合相同的对象,但需要一个额外的实例变量,因此我将内置集合对象子类化。确保在复制我的一个对象时复制此变量的值的最佳方法是什么?

使用旧的 sets 模块,以下代码可以完美运行:

import sets
class Fooset(sets.Set):
def __init__(self, s = []):
sets.Set.__init__(self, s)
if isinstance(s, Fooset):
self.foo = s.foo
else:
self.foo = 'default'
f = Fooset([1,2,4])
f.foo = 'bar'
assert( (f | f).foo == 'bar')

但这不适用于内置的 set 模块。

我能看到的唯一解决方案是重写每个返回复制的集合对象的方法……在这种情况下,我可能还不如不去继承集合对象。当然有一个标准的方法来做到这一点?

(澄清一下,以下代码有效(断言失败):

class Fooset(set):
def __init__(self, s = []):
set.__init__(self, s)
if isinstance(s, Fooset):
self.foo = s.foo
else:
self.foo = 'default'

f = Fooset([1,2,4])
f.foo = 'bar'
assert( (f | f).foo == 'bar')

)

最佳答案

我最喜欢的包装内置集合方法的方式:

class Fooset(set):
def __init__(self, s=(), foo=None):
super(Fooset,self).__init__(s)
if foo is None and hasattr(s, 'foo'):
foo = s.foo
self.foo = foo



@classmethod
def _wrap_methods(cls, names):
def wrap_method_closure(name):
def inner(self, *args):
result = getattr(super(cls, self), name)(*args)
if isinstance(result, set) and not hasattr(result, 'foo'):
result = cls(result, foo=self.foo)
return result
inner.fn_name = name
setattr(cls, name, inner)
for name in names:
wrap_method_closure(name)

Fooset._wrap_methods(['__ror__', 'difference_update', '__isub__',
'symmetric_difference', '__rsub__', '__and__', '__rand__', 'intersection',
'difference', '__iand__', 'union', '__ixor__',
'symmetric_difference_update', '__or__', 'copy', '__rxor__',
'intersection_update', '__xor__', '__ior__', '__sub__',
])

本质上与您在自己的答案中所做的相同,但 loc 更少。如果您想对列表和字典也做同样的事情,那么放入元类也很容易。

关于python - 添加新实例变量的 Python set 类子类化的正确(或最佳)方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/798442/

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