python - 当您的对象可以是实例列表时,Python 开放封闭原则?
问题描述
我有许多可以“jsonify”的不同对象,这些是自定义对象类型:
class Jsonable(ABC):
@abstractmethod
def extract_json():
pass # return json of self
class Organization(Jsonable):
# implements the abstract method, all good here
def extract_json():
return # some json of self, great!
class Feature(Jsonable):
# implements the abstract method, all good here
def extract_json():
return # some json of self, great!
我有一个函数,我想传入许多不同类型的“Jsonable”并为它们获取 json,但有一个问题,“str”类是该函数的有效类型,也是 List[Jsonable]也是有效的,我如何有一个干净的函数来返回数据?
def extract(data: Union[Jsonable, List[Jsonable], str):
if isinstance(data, str):
# do something about string
# not great but I can live with this, it will never change
return data.extract_json() # ok for the standard types (Org above)
# what about List[Jsonable]?
# I have many types, Organization above is one example
如何使这个提取函数不违反 OCP 并获得一种从这些类型中抽象数据的干净方法?我也应该能够从列出的类型中干净地获取 json 吗?
List 不能真正扩展 Jsonable,那么我该如何干净地处理呢?
解决方案
如果你的签名看起来像那样,你基本上是在告诉调用者他们必须传入这三种类型中的一种,你总是知道Jsonable
s have .extract_json()
,所以......
def extract(data: Union[Jsonable, List[Jsonable], str]):
if isinstance(data, str):
return ...
if isinstance(data, list): # given the signature it's implicit everything is jsonable
return [item.extract_json() for item in list]
return item.extract_json()
但是,如果它真的是你在谈论的 JSON,我建议查看json.dump()
的default()
回调,当有一个它不知道如何处理的对象时调用它:
def handle_object(obj):
if isinstance(obj, Jsonable):
return obj.extract_json() # should really return something that's json encodable now
raise TypeError(f'Not sure how to JSONify {obj}')
# ...
json.dumps(anything, default=handle_object)
推荐阅读
- c# - 发送电子邮件时也在我的收件箱中收到电子邮件
- javascript - break 在 for ... of 循环中终止迭代器
- html - PDFKit 使用 Rails 5
- javascript - jquery 选项卡在 Safari ios 中不起作用
- ios - AVAudioCompressedBuffer 到 UInt8 数组,反之亦然
- jsf - 当导航器重新启动时,ap:commandButton 的操作仅在第一次单击(或操作)时重新加载页面
- jquery - 字符串替换功能不适用于带有肤色的表情
- inno-setup - 调整安装程序以避免管理员权限
- c# - 仅在模型的某些部分检查“ModelState.IsValid”
- rest - 太频繁地更新访问令牌是不好的做法吗?