Python: 子类可以重载继承的方法吗?
我正在Google App Engine上制作一个购物车应用。我的代码中有很多类都是从一个基础处理器(handler)派生出来的:
class BaseHandler(webapp.RequestHandler):
def get(self, CSIN=None):
self.body(CSIN)
这是否意味着每个子类的body()
方法都需要有相同的参数?这太麻烦了。其实只有一个子类真正使用了这个参数。那如果我以后添加新的参数呢?我是不是得逐个去修改每个类?
class Detail(BaseHandler):
def body(self, CSIN):
class MainPage(BaseHandler):
def body(self, CSIN=None): #@UnusedVariable
class Cart(BaseHandler):
def body(self, CSIN): #@UnusedVariable
2 个回答
5
在Python中,方法的重载只根据名字来匹配。这意味着
class Base:
def method(self, param2):
print "cheeses"
class NotBase(Base):
def method(self):
print "dill"
obj = NotBase();
obj.method()
会输出dill(,而当你用obj.method("stuff")时就会出错。
不过,在你的情况下,这种行为并不是你想要的。如果你在子类中重载了body
方法,但参数比基类的get
方法需要的少,那么当你在这些类上调用get
方法时就会出错。
8
重写的方法原则上不需要有相同的参数,但它们在调用时必须有相同的形式参数。也就是说,由于任何处理器都可以通过 get
调用 body
,所以它们的参数必须一致。实际上,重写的目的就是让调用者不知道对象的确切类,因此如果它们的参数不相同,通常调用者就不知道该传什么参数。所以,使用不同参数的重写方法可能会有点奇怪。
如果你改变了调用时的参数,那么你确实需要修改函数以匹配。这和继承没有关系,而是关于Python函数是如何工作的。
如果你想要更多的灵活性,可以使用关键字参数,这是一种将字典作为参数传递的高级方式:
class Detail(BaseHandler):
def body(self, **kwargs):
print kwargs['CSIN']
class MainPage(BaseHandler):
def body(self, **kwargs): # can ignore kwargs
class Cart(BaseHandler):
def body(self, **kwargs): # can ignore kwargs
class BaseHandler(webapp.RequestHandler):
def get(self, CSIN=None):
self.body(CSIN = CSIN, some_new_arg = 3)
class SomeNewHandler(BaseHandler):
def body(self, **kwargs):
print kwargs['some_new_arg']
不过,我对这样做的智慧有点怀疑:如果你经常添加新参数,而大多数实现又忽略了大部分参数,那么也许 body
并不真的是这些参数的函数。实际上,这些参数可能是处理器对象的状态,只是恰好作为参数传递而已。显然,这种区别有点主观——对于每个对象只调用一次的函数,传递一个字典和使用 self
作为字典之间并没有太大的实际区别。