覆盖类方法来定义Kwargs - 哪个是Pythonic?

时间:2015-05-11 15:25:48

标签: python override

我正在为数据库创建一个抽象层,我有一个类似于这个定义的超类:

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 Test_B(Test):
    # Subclass defining more specific version of Test.

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

哪个更“Pythonic”?使用超类中的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")

3 个答案:

答案 0 :(得分:4)

第一个。 “明确比隐含更好” - Zen of Python:第2行

答案 1 :(得分:0)

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

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

然后让每个子类调用它来实现自己的find_object

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

使用super时,如果重写方法,保留方法的签名是一个好主意,因为您永远无法确定哪个类super将返回代理。

答案 2 :(得分:0)

skilsuper - 你是对的

  

显式优于隐式

但是,这并不意味着第一个答案更好 - 您仍然可以在第二个解决方案中应用相同的主体:find_object(10, 30, "Pie")是隐式的,但没有任何东西阻止您使用find_object(a=10, b=30, c="Pie") (你应该使用它。)

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