如何使用classmethod工厂函数实现继承
How to achieve inheritance using classmethod factory functions
如何在使用 classmethod
approach for implementing factory functions 时 use/reuse 在 parent class 中实现?
在下面的例子中,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 更深,即有多个 children of class B
。继承层次结构的根在工厂函数中做了一些有用的事情。 Children class应该 re-use 但要添加一些额外的操作。
使用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
创建了一个描述符,当从 class 或 class 调用时绑定 class实例。您必须使用类似以下内容的方法访问原始函数:
res = A.__dict__['from_jdata'].__func__(B, data)
要使其工作,但只需使用 super
,这就是它的用途。
如何在使用 classmethod
approach for implementing factory functions 时 use/reuse 在 parent class 中实现?
在下面的例子中,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 更深,即有多个 children of class B
。继承层次结构的根在工厂函数中做了一些有用的事情。 Children class应该 re-use 但要添加一些额外的操作。
使用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
创建了一个描述符,当从 class 或 class 调用时绑定 class实例。您必须使用类似以下内容的方法访问原始函数:
res = A.__dict__['from_jdata'].__func__(B, data)
要使其工作,但只需使用 super
,这就是它的用途。