覆盖 Class 定义 Kwargs 的方法——哪个是 Pythonic?

Overwriting Class Methods to define Kwargs - Which is Pythonic?

我正在处理数据库的抽象层,我有一个超级 class 定义类似于:

class Test():
    __init__(self, object):
        self.obj = object

    @classmethod
    def find_object(cls, **kwargs):
        # Code to search for object to put in parameter using kwargs.

        return cls(found_object)

然后我将超级class分解为子class子,这些子class更具体地表示它们所代表的对象。

class Test_B(Test):
    # Subclass defining more specific version of Test.

现在,测试的每个单独的子class 都有预定义的搜索条件。例如,Test_B 需要一个对象,其中 a = 10,b = 30,c = "Pie"。

哪个会更多"Pythonic"?使用超级 class:

中的 find_object 方法
testb = Test_B.find_object(a=10, b=30, c="Pie")

或覆盖 find_object 方法以期望 a、b 和 c 作为参数:

@classmethod
def find_object(cls, a, b, c):
    return super().find_object(a=a, b=b, c=c)

testb = Test_B.find_object(10, 30, "Pie")

第一个。 "Explicit is better than implicit" - Zen of Python:第 2 行

Test.find_object不打算直接使用,所以我将其命名为

@classmethod
def _find_object(cls, **kwargs):
    ...

然后让每个 child class 调用它来实现自己的 find_object:

@classmethod
def find_object(cls, a, b, c):
    return super()._find_object(a=a, b=b, c=c)

使用 super 时,最好在覆盖方法时保留方法的签名,因为您永远无法确定 class super 将 return 一个代理。

- 你是对的

Explicit is better than implicit

然而,这并不意味着第一个答案更好 - 您仍然可以在第二个解决方案上应用相同的原则:find_object(10, 30, "Pie") 是隐含的,但没有什么能阻止您使用 find_object(a=10, b=30, c="Pie") (你应该使用它)。

第一个解决方案有问题,因为您可能会忘记一个参数(例如,find_object(a=10, b=30))。在这种情况下,第一个解决方案将让它滑动,但第二个解决方案将发出一个 TypeError 说你错过了一个论点。