我如何使用 Super() (Python 2/3) 从基数 class 正确继承?
How do I properly inherit from a base class using Super() (Python 2/3)?
我有两个 class,一个是基础 class,第二个需要从基础 class 继承。我在这种情况下正确使用 super() 的问题。
当我创建 class TestService
时,它继承自 ServiceMap
,所以我认为所需的 MRO 应该是:TestService -> ServiceMap -> OrderedDict。
这是否意味着在 TestService
的初始化程序中我应该调用 super(ServiceMap, self).__init__(value=value, kwargs=None)
?然后初始化剩下的TestServiceclass? (如下所示)。或者我是否需要在每个继承的 class 中从 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
您需要使用:
class TestService(ServiceMap):
def __init__(self, url, connection, value=None):
super(TestService, self).__init__(value=value)
这会调用父 class 的 __init__()
,在您的情况下 ServiceMap
并创建所需的 mro。
super()
的第一个参数是您希望获得父级 class 的点。通常,这与您当前定义的 class 相同,因此您将获得当前定义的 class 的父级的 __init__
方法。在这种情况下,您要使用 super(TestService, self)
。有时,您将定义 TestService
的 subclass 而未定义 __init__
方法。这意味着将使用 TestService
__init__
方法。由于 TestService
显式地将 TestService
用于 super()
,您仍将获得正确的父 __init__
方法。如果您使用 self.__class__
,这可能很诱人,那条线将进入无限递归子 class。
当你在一个superclass中扩展一个方法时使用super
,也就是说你想要运行 superclass的方法代码以及在 child class.
您的示例代码不正确:您需要调用
super(TestService, self)__ init __ (value=value)
到运行superclass的__init__方法,然后就可以继续初始化childclass.
如果您不扩展方法,则不需要 super
调用,只需不要在 child class 和 superclass 代码将 运行.
如果要重写方法,请在子class 中定义方法,但不要调用super
。
在Python3中你不需要传递参数给super
,你可以调用
super().some_method(arg1, arg2)
(已编辑以反映 Zondo 的评论)
用Python3继承的简单方法是
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()
这为您提供了一个 "proper" ServiceMap,您可以对其进行补充
我有两个 class,一个是基础 class,第二个需要从基础 class 继承。我在这种情况下正确使用 super() 的问题。
当我创建 class TestService
时,它继承自 ServiceMap
,所以我认为所需的 MRO 应该是:TestService -> ServiceMap -> OrderedDict。
这是否意味着在 TestService
的初始化程序中我应该调用 super(ServiceMap, self).__init__(value=value, kwargs=None)
?然后初始化剩下的TestServiceclass? (如下所示)。或者我是否需要在每个继承的 class 中从 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
您需要使用:
class TestService(ServiceMap):
def __init__(self, url, connection, value=None):
super(TestService, self).__init__(value=value)
这会调用父 class 的 __init__()
,在您的情况下 ServiceMap
并创建所需的 mro。
super()
的第一个参数是您希望获得父级 class 的点。通常,这与您当前定义的 class 相同,因此您将获得当前定义的 class 的父级的 __init__
方法。在这种情况下,您要使用 super(TestService, self)
。有时,您将定义 TestService
的 subclass 而未定义 __init__
方法。这意味着将使用 TestService
__init__
方法。由于 TestService
显式地将 TestService
用于 super()
,您仍将获得正确的父 __init__
方法。如果您使用 self.__class__
,这可能很诱人,那条线将进入无限递归子 class。
当你在一个superclass中扩展一个方法时使用super
,也就是说你想要运行 superclass的方法代码以及在 child class.
您的示例代码不正确:您需要调用
super(TestService, self)__ init __ (value=value)
到运行superclass的__init__方法,然后就可以继续初始化childclass.
如果您不扩展方法,则不需要 super
调用,只需不要在 child class 和 superclass 代码将 运行.
如果要重写方法,请在子class 中定义方法,但不要调用super
。
在Python3中你不需要传递参数给super
,你可以调用
super().some_method(arg1, arg2)
(已编辑以反映 Zondo 的评论)
用Python3继承的简单方法是
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()
这为您提供了一个 "proper" ServiceMap,您可以对其进行补充