python - 如何使用类方法工厂函数实现继承
问题描述
classmethod
使用实现工厂函数的方法时,如何在父类中使用/重用实现?
在下面的示例中,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
. 继承层次的根在工厂函数中做了一些有用的事情。子类应该重用它,但添加一些额外的操作。
解决方案
使用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'}
请注意,您尝试执行的操作将不起作用,因为在从class 或 instance@classmethod
调用时创建了一个绑定类的描述符。您必须使用以下方式访问原始函数:
res = A.__dict__['from_jdata'].__func__(B, data)
为了让它工作,但只是使用super
,这就是它的用途。
推荐阅读
- javascript - Javascript验证密码字段输入
- javascript - 意外的关键字或标识符.ts(1434) | 声明后缺少或未立即执行函数实现.ts(2391)
- linux - grep 并剪切特定模式
- visual-studio - 为什么我在手机上安装 Xamarin.Forms 应用程序 apk 时总是出现空白屏幕
- node.js - 无法添加 CUSTOM_ELEMENTS_SCHEMA
- python - Photoimage 无法在导入的类上加载图像
- python - Python从列表中删除数字并只保留单词,反之亦然
- primefaces - jfwid 被替换,网站正在刷新
- svg - 矢量图形导入呈现黑色图像
- php - 从PHP中的数组中提取值