gpt4 book ai didi

python - 基于输入类型选择行为的大多数 Pythonic 方式?

转载 作者:太空宇宙 更新时间:2023-11-04 01:46:23 25 4
gpt4 key购买 nike

我有一些函数的实现细节取决于传递给它们的对象类型(具体来说,就是选择正确的方法来链接 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())

字典选项的重复代码和行数较少,但 if 阶梯让 PyC​​harm 和 MyPy 更快乐(尤其是类型检查)。

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

最佳答案

这正是多态旨在解决的问题类型,而解决此类问题的“Pythonic”方式就是使用多态。按照“封装变化的内容”的概念,我建议创建一个所有类都实现的基本“接口(interface)”,然后只需在所有类上调用同名的方法。

我将“接口(interface)”放在引号中,因为 Python 并不真正拥有 OOP 中众所周知的接口(interface)。因此,您将不得不使用子类并手动强制执行方法签名(即小心)。

演示:

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()

关于python - 基于输入类型选择行为的大多数 Pythonic 方式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59011408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com