我正在实现一个与集合几乎相同的对象,但需要一个额外的实例变量,所以我将内置集合对象子类化.在复制我的一个对象时,确保复制此变量的值的最佳方法是什么?
I'm implementing an object that is almost identical to a set, but requires an extra instance variable, so I am subclassing the built-in set object. What is the best way to make sure that the value of this variable is copied when one of my objects is copied?
使用旧的 sets 模块,以下代码完美运行:
Using the old sets module, the following code worked perfectly:
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 模块.
but this does not work using the built-in set module.
我能看到的唯一解决方案是覆盖每个返回复制集合对象的单个方法......在这种情况下,我可能不会费心子类化集合对象.肯定有标准的方法可以做到这一点吗?
The only solution that I can see is to override every single method that returns a copied set object... in which case I might as well not bother subclassing the set object. Surely there is a standard way to do this?
(澄清一下,以下代码不起作用(断言失败):
(To clarify, the following code does not work (the assertion fails):
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')
)
我最喜欢的封装内置集合方法的方式:
My favorite way to wrap methods of a built-in collection:
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 更少.如果您也想对列表和字典做同样的事情,也很容易放入元类.
Essentially the same thing you're doing in your own answer, but with fewer loc. It's also easy to put in a metaclass if you want to do the same thing with lists and dicts as well.
这篇关于对 Python 集类进行子类化、添加新实例变量的正确(或最佳)方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!