Reputation: 1043
I'm trying to wrap my head around how to utilize inheritance in some code I'm writing for an API. I have the following parent class which holds a bunch of common variables that I'd like to instantiate once, and inherit with other classes to make my code look cleaner:
class ApiCommon(object):
def __init__(self, _apikey, _serviceid=None, _vclversion=None,
_aclname=None, _aclid=None):
self.BaseApiUrl = "https://api.fastly.com"
self.APIKey = _apikey
self.headers = {'Fastly-Key': self.APIKey}
self.ServiceID = _serviceid
self.VCLVersion = _vclversion
self.ACLName = _aclname
self.ACLid = _aclid
self.Data = None
self.IP = None
self.CIDR = None
self.fullurl = None
self.r = None
self.jsonresp = None
self.ACLcomment = None
self.ACLentryid = None
And I am inheriting it in another class below, like so in a lib file called lib/security.py
:
from apicommon import ApiCommon
class EdgeAclControl(ApiCommon):
def __init__(self):
super(EdgeAclControl, self).__init__()
...
def somemethodhere(self):
return 'stuff'
When I instantiate an object for ApiCommon(object)
, I can't access the methods in EdgeAclControl(ApiCommon)
. Example of what I'm trying which isn't working:
from lib import security
gza = security.ApiCommon(_aclname='pytest', _apikey='mykey',
_serviceid='stuffhere', _vclversion=5)
gza.somemethodhere()
How would I instantiate ApiCommon
and have access to the methods in EdgeAclControl
?
Upvotes: 0
Views: 1402
Reputation: 104712
Your current code appears to be trying to use inheritance backwards. When you create an instance of ApiCommon
, it will only get the methods defined in that base class. If you want to get methods from a subclass, you need to create an instance of the subclass instead.
So the first fix you need to make is to change gza = security.ApiCommon(...)
to gza = EdgeAclControl(...)
(though depending on how you're doing your imports, you might need to prefix the class name with a module).
The second issue is that your EdgeAclControl
class doesn't take the arguments that its base class needs. Your current code doesn't pass any arguments to super(...).__init__
, which doesn't work since the _apikey
parameter is required. You could repeat all the arguments again in the subclass, but a lot of the time it's easier to use variable-argument syntax instead.
I suggest that you change EdgeAclControl.__init__
to accept *args
and/or **kwargs
and pass on those variable arguments when it calls its parent's __init__
method using super
. That would look like this:
def __init__(self, *args, **kwargs):
super(EdgeAclControl, self).__init__(*args, **kwargs)
Note that if, as in this example, you're not doing anything other than calling the parent __init__
method in the derived __init__
method, you could get the same effect by just deleting the derived version entirely!
It's likely that your real code does something in EdgeAclControl.__init__
, so you may need to keep it in some form. Note that it can take arguments normally in addition to the *args
and **kwargs
. Just remember to pass on the extra arguments, if necessary, when calling the base class.
Upvotes: 2
Reputation: 101
May I ask why you have to instantiate an ApiCommon
object? I don't see any point of doing so.
If you insist doing that, you have to add methods in superclass and then subclass may override theses methods. But you still couldn't access methods of EdgeAclControl
from ApiCommon
object
Upvotes: 0