简体   繁体   English

类继承:访问子类中的父类参数?

[英]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. 我正在尝试将我的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 : 而且我在下面的另一个类中继承了它,就像在一个名为lib/security.py的lib文件中一样:

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) . 实例化ApiCommon(object) ,无法访问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 ? 我将如何实例ApiCommon ,并获得在方法EdgeAclControl

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. 当创建ApiCommon的实例时,它将仅获取该基类中定义的方法。 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). 因此,您需要做的第一个修复是将gza = security.ApiCommon(...)更改为gza = EdgeAclControl(...) (尽管根据您执行导入的方式,您可能需要在类名前添加前缀与模块)。

The second issue is that your EdgeAclControl class doesn't take the arguments that its base class needs. 第二个问题是EdgeAclControl类没有采用其基类所需的参数。 Your current code doesn't pass any arguments to super(...).__init__ , which doesn't work since the _apikey parameter is required. 您当前的代码未将任何参数传递给super(...).__init__ ,这是无效的,因为需要_apikey参数。 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 . 我建议您更改EdgeAclControl.__init__以接受*args和/或**kwargs并在它们使用super调用其父级的__init__方法时传递这些变量参数。 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! 请注意,如在本示例中那样,除了在派生的__init__方法中调用父__init__方法之外,您没有做任何其他事情,您可以通过完全删除派生的版本来获得相同的效果!

It's likely that your real code does something in EdgeAclControl.__init__ , so you may need to keep it in some form. 您的真实代码很可能在EdgeAclControl.__init__执行了某些EdgeAclControl.__init__ ,因此您可能需要将其保留为某种形式。 Note that it can take arguments normally in addition to the *args and **kwargs . 请注意,除了*args**kwargs之外,它还可以正常接收其他*args Just remember to pass on the extra arguments, if necessary, when calling the base class. 只要记住,在调用基类时,如有必要,传递额外的参数。

May I ask why you have to instantiate an ApiCommon object? 请问为什么必须实例化一个ApiCommon对象? 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 但是您仍然无法从ApiCommon对象访问EdgeAclControl方法

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM