当您的对象可能是实例列表时,使用“ Python开放式封闭原则”?

时间:2019-07-18 18:52:05

标签: python design-patterns open-closed-principle

我有很多可以“ 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”类是此函数的有效类型,还有一个列表[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,所以我应该如何处理呢?

1 个答案:

答案 0 :(得分:0)

如果您的签名看起来像这样,则基本上是在告诉呼叫者他们必须通过这三种类型之一,并且您始终知道Jsonable个具有.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()的{​​{1}}回调,当有对象不知道如何处理时会调用该回调与:

default()