For the following example code, parent class PPC uses slef.forward(x)
to call the function of child class.
I couldn’t understand the following questions:
- forward is not a virtual function, how could parent class call it? what is the PEP link about my question? is there any explanation of python language?
Python doesn’t have virtual methods.
- how does parent class find the forward? via which dict or list?
It doesn’t. This will only work in an instance of PPSub.
- in my example code, if I use abstractmethod, should it be a better syntax?
Better style and practice, definitely. Syntax is syntax. If its legal
syntax, you’re good.
Let’s look at this more closely.
PPC is an abstract class. It uses .forward(), but doesn’t provide one.
If you instantiate an instance of PPC, call won’t work.
PPSub is a concrete subclass of PPC: it supplies a .forward()
implementation. If you make an instance of PPSub, its call method
will work.
When you call ps1(9)
it goes to the call method. PPSub doesn’t
implement this, but its superclass does. So that gets used. That method
in turn calls .forward
. But it finds that from self
, which is an
instance of PPSub, and PPSub does implement .forward
.
These days Python has support for making abstract classes more
rigorously. Let’s update your code using it:
from abc import ABC, abstractmethod
@ABC
class PPC():
def kkfunc(self):
print('kk func in parent class')
def __call__(self, x):
xx= self.forward(x)
# print('call function === ', x)
return xx
@abstractmethod
def forward(self, x):
raise NotImplementedError("no .forward method")
class PPSub(PPC):
def __init__(self):
pass
def pfunc(self):
print('in sub class')
def forward(self, x):
print('forward function in ppsub class===', x)
return x+1
ps1 = PPSub()
xxx = ps1(9)
This doesn’t change how any of the classes work, but the @ABC
and
@abstractmethod
decorator arrange that you can’t actually make an
instance of PPC. The @ABC
decorator makes the class check that none of
its methods are abstractmethods.
PPSub will inherit that behaviour, but since it provides a .forward
which is not an abstractmethod, it has no abstractmethods and you’re
allowed to make one.
Cheers,
Cameron Simpson cs@cskk.id.au