dobbs
dobbs

Reputation: 1043

Class inheritance: Access parent class arguments in a subclass?

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

Answers (2)

Blckknght
Blckknght

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

ZYYYY
ZYYYY

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

Related Questions