如何使用Super()(Python 2/3)从基类中正确继承?

时间:2016-03-28 11:22:29

标签: python python-2.7 python-3.x super

我有两个类,一个是基类,第二个类需要从基类继承。我在这种情况下正确使用super()的问题。

当我创建我的课程TestService时,它继承自ServiceMap,因此我认为所需的MRO应该是:TestService - > ServiceMap - > OrderedDict。

这是否意味着我的初始化程序TestService我应该致电super(ServiceMap, self).__init__(value=value, kwargs=None)?然后初始化TestService类的其余部分? (如下所示)。或者我是否需要在每个继承的类中从ServiceMap重新创建初始值设定项?我真的不想重新创建该代码,因为会有多种类型的服务继承自ServiceMap类型。

请提供一些超级()指导!

由于

    from collections import OrderedDict
    from sys import version_info
    from inspect import ismethod
    import json
    import six
    import copy

    class ServiceMap(OrderedDict):
        _map = None
        #----------------------------------------------------------------------
        def __init__(self, value=None, **kwargs):
            """Initializer object"""
            self._map = OrderedDict()
            if value:
                if isinstance(value, dict):
                    for k,v in six.iteritems(value):
                        if isinstance(v, dict):
                            v = ServiceMap(value=v)
                        self._map[k] = v
                        del k,v
            if kwargs:
                for k,v in six.iteritems(kwargs):
                    self._map[k] = v
        #----------------------------------------------------------------------
        def items(self):
            return six.iteritems(self._map)
        #----------------------------------------------------------------------
        def iteritems(self):
            return six.iteritems(self._map)
        #----------------------------------------------------------------------
        def __iter__(self):
            return self._map.__iter__()
        #----------------------------------------------------------------------
        def next(self):
            return self._map.next()
        #----------------------------------------------------------------------
        def __setitem__(self, k, v):
            self._map[k] = v
        #----------------------------------------------------------------------
        def __getitem__(self, k):
            if k not in self._map:
                # if parameter k DNE, create a empty object as ServiceMap
                self[k] = ServiceMap()
            return self._map[k]
        #----------------------------------------------------------------------
        def __setattr__(self, k, v):
            if k == '_map':
                super(ServiceMap, self).__setattr__(k,v)
            else:
                self[k] = v
        #----------------------------------------------------------------------
        def __getattr__(self, k):
            if k == '_map':
                super(ServiceMap, self).__getattr__(k)
            else:
                return self[k]
        #----------------------------------------------------------------------
        def __delattr__(self, key):
            return self._map.__delitem__(key)
        #----------------------------------------------------------------------
        def __contains__(self, k):
            return self._map.__contains__(k)
        #----------------------------------------------------------------------
        def __str__(self):
            """represents the object as a string"""
            return json.dumps(self.as_dictionary())
        #----------------------------------------------------------------------
        def __repr__(self):
            return str(self)
        #----------------------------------------------------------------------
        def as_dictionary(self):
            """
            recursively iterate the object inorder to conver the ServiceMap object
            to a traditional dictionary type object."""
            vals = {}
            for k,v in self.items():
                if type(v) is ServiceMap:
                    vals[k] = v.as_dictionary()
                else:
                    vals[k] = v
                del k,v
            return vals
        #----------------------------------------------------------------------
        def values(self):
            return self._map.values()
        #----------------------------------------------------------------------
        def __cmp__(self, value):
            value = ServiceMap.compare(value)
            return self._map.__cmp__(value)
        #----------------------------------------------------------------------
        def __eq__(self, value):
            value = ServiceMap.compare(value)
            if not isinstance(value, dict):
                return False
            return self._map.__eq__(value)
        #----------------------------------------------------------------------
        def __ge__(self, value):
            value = ServiceMap.compare(value)
            return self._map.__ge__(value)
        #----------------------------------------------------------------------
        def __gt__(self, value):
            value = ServiceMap.compare(value)
            return self._map.__gt__(value)
        #----------------------------------------------------------------------
        def __le__(self, value):
            value = ServiceMap.compare(value)
            return self._map.__le__(value)
        #----------------------------------------------------------------------
        def __lt__(self, value):
            value = ServiceMap.compare(value)
            return self._map.__lt__(value)
        #----------------------------------------------------------------------
        def __ne__(self, value):
            value = ServiceMap.compare(value)
            return self._map.__ne__(value)
        #----------------------------------------------------------------------
        def __delitem__(self, key):
            return self._map.__delitem__(key)
        #----------------------------------------------------------------------
        def __len__(self):
            return self._map.__len__()
        #----------------------------------------------------------------------
        def clear(self):
            self._map.clear()
        #----------------------------------------------------------------------
        def copy(self):
            return copy.deepcopy(self)
        #----------------------------------------------------------------------
        def get(self, key, default=None):
            return self._map.get(key, default)
        #----------------------------------------------------------------------
        def has_key(self, key):
            return key in self._map
        #----------------------------------------------------------------------
        def iterkeys(self):
            return self._map.iterkeys()
        #----------------------------------------------------------------------
        def itervalues(self):
            return self._map.itervalues()
        #----------------------------------------------------------------------
        def keys(self):
            return self._map.keys()
        #----------------------------------------------------------------------
        def pop(self, key, default=None):
            return self._map.pop(key, default)
        #----------------------------------------------------------------------
        def popitem(self):
            return self._map.popitem()
        #----------------------------------------------------------------------
        def setdefault(self, key, default=None):
            self._map.setdefault(key, default)
        #----------------------------------------------------------------------
        def update(self, *args, **kwargs):
            if len(args) != 0:
                self._map.update(*args)
            self._map.update(kwargs)
        #----------------------------------------------------------------------
        def viewitems(self):
            return self._map.viewitems()
        #----------------------------------------------------------------------
        def viewkeys(self):
            return self._map.viewkeys()
        #----------------------------------------------------------------------
        def viewvalues(self):
            return self._map.viewvalues()
        #----------------------------------------------------------------------
        @classmethod
        def fromkeys(cls, seq, value=None):
            """
            creates a ServiceMap object from a set of keys with default values
            This allows the creation of template objects.
            """
            val = ServiceMap()
            val._map = OrderedDict.fromkeys(seq, value)
            return val
        #----------------------------------------------------------------------
        @classmethod
        def compare(self, value):
            if type(value) is ServiceMap:
                return value._map
            else:
                return value

    class TestService(ServiceMap):
        _con = None
        _url = None
        def __init__(self, url, connection, value=None):
            super(ServiceMap, self).__init__(value=value)
            self._url = None
            self._con = None

4 个答案:

答案 0 :(得分:1)

使用Python 3继承的简单方法是

class TestService(ServiceMap):

  def __init__(self, value=None, **kwargs):
    super().__init__(value, kwargs) #equivalent to ServiceMap.__init__(self,value, kwargs) 
    code_specific to this class()

这为您提供了一个“适当的”ServiceMap,然后您可以补充

答案 1 :(得分:0)

您需要使用:

class TestService(ServiceMap):
    def __init__(self, url, connection, value=None):
        super(TestService, self).__init__(value=value)

这将调用父类的__init__(),在您的情况下ServiceMap并创建所需的mro。

答案 2 :(得分:0)

public class StudioEnableEvent : PubSubEvent<bool> { } 的第一个参数是您希望获得父类的点。通常,它与您当前定义的类相同,因此您将获得当前正在定义的类的父级的super()方法。在这种情况下,您要使用__init__。有时,您将定义super(TestService, self)的子类,而不是定义TestService方法。这意味着将使用__init__ TestService方法。由于__init__明确使用了TestService TestService,您仍然会获得正确的父super()方法。如果您使用__init__,这可能很诱人,那么该行将进入子类的无限递归。

答案 3 :(得分:0)

在扩展超类中的方法时使用<TextView android:id="@+id/title" android:layout_width="wrap_content" android:layout_height="wrap_content" "/> ,即您希望运行超类的方法代码以及子类中的代码。

您的示例代码不正确:您需要致电 super运行超类的__ init __方法,然后您可以继续初始化子类。

如果您没有扩展方法,则不需要进行super(TestService, self)__ init __ (value=value)调用,只是不要在子类中定义方法,并且超类代码将运行。

如果要覆盖方法,请在子类中定义方法,但不要调用super

在Python3中,你不需要将参数传递给super,你可以直接调用 super

(编辑反映Zondo的评论)