使用classmethod
approach for implementing factory functions时如何在父类中使用/重用实现?
在下面的示例中,class A
很好,但是class B
坏了。
class A(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)
@classmethod
def from_jdata(cls, data):
if '_id' in data:
data['uuid'] = data['_id']
del data['_id']
return cls(**data)
class B(A):
def __init__(self, **kwds):
super(B, self).__init__(**kwds)
@classmethod
def from_jdata(cls, data):
# goal: make an instance of B,
# using the logic that is implemented in A.from_jdata
# But does some extra stuff, akin to:
res = A.from_jdata(B, data)
res.__dict__['extra']='set'
return res
上下文是我正在尝试基于JSON配置数据实例化实例。继承层次结构比只有两个类更深,即,有多个class B
的子级。继承层次结构的根在工厂功能中起到了一些有用的作用。子类应该重新使用它,但要增加一些其他操作。
答案 0 :(得分:1)
当然使用super
:
class A(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)
@classmethod
def from_jdata(cls, data):
if '_id' in data:
data['uuid'] = data['_id']
del data['_id']
return cls(**data)
class B(A):
def __init__(self, **kwds):
super(B, self).__init__(**kwds)
@classmethod
def from_jdata(cls, data):
# goal: make an instance of B,
# using the logic that is implemented in A.from_jdata
# But does some extra stuff, akin to:
res = super().from_jdata(data)
# res = super(B, cls).from_jdata(data) # in python 2
res.__dict__['extra']='set'
return res
实际情况:
In [6]: b = B.from_jdata({'_id':42, 'foo':'bar'})
In [7]: vars(b)
Out[7]: {'foo': 'bar', 'uuid': 42, 'extra': 'set'}
请注意,您尝试执行的操作无效,因为@classmethod
创建了一个描述符,该描述符在从类或实例调用时绑定了该类。您将必须使用以下方式访问原始函数:
res = A.__dict__['from_jdata'].__func__(B, data)
要使其正常工作,而只需使用super
,这就是它的作用。