2016-03-28 69 views
0

我有两个类,一个是基类,第二个需要从基类继承。我的问题与在这种情况下正确使用super()。如何正确使用Super()(Python 2/3)从基类继承?

当我创建我的类TestService时,它继承自ServiceMap,所以我在想所需的MRO应该是:TestService - > ServiceMap - > OrderedDict。

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

请提供一些super()指导!

感谢

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 
+0

你真的你*试过*你显示的代码?有什么问题?另外,为什么你完全重新实现'OrderedDict'只是为了重定向到'_map'属性(注意这是* class属性* - http://stackoverflow.com/q/1680528/3001761)。 – jonrsharpe

+0

@jonrsharpe - 尽管BaseClass应初始化_map对象,但我的self._map始终显示为None。 –

+1

然后展示一个[mcve],就这个问题而言,绝大多数你发布的代码都是不相关的。 – jonrsharpe

回答

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,然后你可以补充

+2

这是仅Python3。这个问题也被标记为“python2.7”。 –

0

您需要使用:

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

这将调用父类的__init__(),你的情况ServiceMap并创建所需的MRO。

0

super()给出了它的第一个参数,您希望获得父类的位置。通常,这与您当前定义的类相同,以便您可以获得当前定义的类的父级方法__init__。在这种情况下,您想使用super(TestService, self)。有时,您将定义TestService的子类,并且您没有定义方法__init__。这意味着将使用TestService__init__方法。由于TestService明确使用TestServicesuper(),您仍然会得到正确的父项__init__方法。如果您使用self.__class__,这可能是诱人的,那么该行将进入子类的无限递归。

0

在超类中扩展方法时使用super,即要运行超类方法的代码以及子类中的代码。

您的示例代码不正确:您需要调用 super(TestService, self)__ init __ (value=value)来运行超类的__ init __方法,然后您可以继续初始化子类。

如果您没有扩展方法,则不需要调用super,只是不要在子类中定义方法,并且超类代码将运行。

如果您重写某个方法,请在子类中定义该方法,但不要调用super

在Python3你不需要传递参数给super,你可以叫 super().some_method(arg1, arg2)

(编辑以反映Zondo的评论)