覆盖类方法来定义Kwargs-哪一个是Pythonic?
我正在处理数据库的抽象层,我定义了一个类似于以下内容的超类:覆盖类方法来定义Kwargs-哪一个是Pythonic?,python,overriding,Python,Overriding,我正在处理数据库的抽象层,我定义了一个类似于以下内容的超类: 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_o
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_B需要一个a=10、B=30、c=“Pie”的对象
哪一个更像“蟒蛇”?使用超类中的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")
第一个。“显式优于隐式”-:第2行。“显式优于隐式”-:第2行
测试。find_object
不打算直接使用,因此我将命名它
@classmethod
def _find_object(cls, **kwargs):
...
然后让每个子类调用它来实现自己的find\u对象
:
@classmethod
def find_object(cls, a, b, c):
return super()._find_object(a=a, b=b, c=c)
使用
super
时,最好在重写方法时保留其签名,因为您永远无法确定哪个类super
将返回代理。测试。find_object
不打算直接使用,因此我将其命名为
@classmethod
def _find_object(cls, **kwargs):
...
然后让每个子类调用它来实现自己的find\u对象
:
@classmethod
def find_object(cls, a, b, c):
return super()._find_object(a=a, b=b, c=c)
使用super
时,最好在重写方法时保留方法的签名,因为您永远无法确定哪个类super
将返回代理。-您说得对
显性比隐性好
然而,这并不意味着第一个答案更好——您仍然可以在第二个解决方案上应用相同的原则:find_object(10,30,“Pie”)
是隐式的,但是没有什么可以阻止您使用find_object(a=10,b=30,c=“Pie”)
(您应该使用它)
第一种解决方案是有问题的,因为您可能会忘记一个参数(例如,find_object(a=10,b=30)
)。在这种情况下,第一个解决方案将让它滑动,但第二个解决方案将发出一个类型错误
,表示您缺少一个参数。-关于
显性比隐性好
然而,这并不意味着第一个答案更好——您仍然可以在第二个解决方案上应用相同的原则:find_object(10,30,“Pie”)
是隐式的,但是没有什么可以阻止您使用find_object(a=10,b=30,c=“Pie”)
(您应该使用它)
第一种解决方案是有问题的,因为您可能会忘记一个参数(例如,
find_object(a=10,b=30)
)。在这种情况下,第一个解决方案会让它滑动,但第二个解决方案会发出一个TypeError
,表示您缺少一个参数。为什么不编写分派器函数,它选择正确的类向其传递kwargs?为什么不编写分派器函数,它选择正确的类向其传递kwargs?不。“简单比复杂好。”-第3行。“简单胜于复杂。”-第3行公平点。不过这两个都是运行时错误(可能find_object会抛出ObjectNotFound
或类似的错误),所以我看不到增加的复杂性有什么好处。我不确定我是否理解您的意思。如果在第二种情况下意外使用find_object(a=10,b=30)
,则不会出现运行时错误。我试过了,得到了TypeError:find_object()正好有4个参数(3个给定)
My bad,又错了:(-edit:I刚试过,这是一个运行时错误。你在使用IDE吗?ipython-I script.py
但是如果调用从未发生,代码运行良好,例如如果False:find_object(a=1,b=2)
?公平点。不过这两个都是运行时错误(可能find\u object会抛出ObjectNotFound
或类似的错误),所以我看不出增加的复杂性有什么好处。我不确定我是否理解您的意思。如果您不小心使用了find\u object(a=10,b=30)
在第二种情况下,它不会是运行时错误。我尝试了它,得到了TypeError:find\u object()正好有4个参数(给定3个)
我的错误,又错了:(-edit:我刚刚尝试过,这是一个运行时错误。您使用的是IDE吗?ipython-I script.py
但是如果调用从未发生,代码运行良好,例如if False:find_object(a=1,b=2)
?