基于输入类型选择行为的最Pythonic方法? 如果是梯子字典

我有一些函数,这些函数的实现细节取决于传递给它们的对象的类型(具体来说,是选择链接Django模型以生成QuerySet的正确方法)。以下两个选项中的哪一个是更Pythonic的实现方式?

如果是梯子

def do_something(thing: SuperClass) -> "QuerySet[SomethingElse]":
    if isinstance(thing,SubClassA):
        return thing.property_set.all()
    if isinstance(thing,SubClassB):
        return thing.method()
    if isinstance(thing,SubClassC):
        return a_function(thing)
    if isinstance(thing,SubClassD):
        return SomethingElse.objects.filter(some_property__in=thing.another_property_set.all())
    return SomethingElse.objects.none()

字典

def do_something(thing: SuperClass) -> "QuerySet[SomethingElse]":
    return {
        SubClassA: thing.property_set.all(),SubClassB: thing.method(),SubClassC: a_function(thing),SubClassD: SomethingElse.objects.filter(some_property__in=thing.another_property_set.all()),}.get(type(thing),SomethingElse.objects.none())

Dictionary选项的重复代码更少,行数更少,但是if梯子使PyCharm和MyPy更加快乐(尤其是使用类型检查)。

我假设两者之间的任何性能差异都可以忽略不计,除非它位于经常调用的例程的内部循环中(如>> 1请求/秒)。

yin088 回答:基于输入类型选择行为的最Pythonic方法? 如果是梯子字典

这正是多态性旨在解决的问题的类型,而解决该问题的“ Pythonic”方法是使用多态性。遵循“封装变化的内容”的概念,我建议创建一个所有类都实现的基本“接口”,然后在所有类上调用同名的方法。

我将“接口”放在引号中,因为Python并没有真正的接口,因为它们在OOP中是众所周知的。因此,您必须使用子类,并手动执行方法签名(即要小心)。

演示:

class SuperClass:

    # define the method signature here (mostly for documentation purposes)
    def do_something(self):
        pass

class SubClassA(SuperClass):

    # Be careful to override this method with the same signature as shown in
    # SuperClass. (In this case,there aren't any arguments.)
    def do_something(self):
        print("Override A")

class SubClassB(SuperClass):

    def do_something(self):
        print("Override B")

if __name__ == '__main__':
    import random

    a = SubClassA()
    b = SubClassB()

    chosen = random.choice([a,b])

    # We don't have to worry about which subclass was chosen,because they
    # share the same interface. That is,we _know_ there will be a
    # `do_something` method on it that takes no arguments.
    chosen.do_something()
本文链接:https://www.f2er.com/3044354.html

大家都在问