考虑到Python 3即将推出,我确信这是大多数python开发人员的主题.一些问题让我们朝着正确的方向前进:
你是否会同时维护python 2和python 3版本,或者你只需要一个python 3版本一旦完成?
注意:使用Python的flyweight实现的一部分
import weakref
class CarModel:
_models = weakref.WeakValueDictionary()
def __new__(cls, model_name, *args, **kwargs):
model = cls._models.get(model_name)
if not model:
model = super().__new__(cls)
cls._models[model_name] = model
return model
def __init__(self, model_name, air=False):
if not hasattr(self, "initted"):
self.model_name = model_name
self.air = air
self.initted=True
Run Code Online (Sandbox Code Playgroud)
问题1>什么super()
意思?这是否意味着父类CarModel
?
问题2>我也很难理解该功能的__new__
工作原理?具体来说,以下行.
model = super().__new__(cls)
Run Code Online (Sandbox Code Playgroud)
说明__new__
:
构造函数被调用
__new__
而不是__init__
,并且只接受一个参数,即正在构造的类(在构造对象之前调用它,因此没有自参数).它还必须返回新创建的对象.
究竟是为什么
A.__init__()
B.__init__()
D.__init__()
Run Code Online (Sandbox Code Playgroud)
由以下代码打印?特别是:
为什么C.__init__()
不打印?
为什么C.__init__()
打印super().__init__()
而不是A.__init__(self)
?
#!/usr/bin/env python3
class A(object):
def __init__(self):
super(A, self).__init__()
print("A.__init__()")
class B(A):
def __init__(self):
A.__init__(self)
print("B.__init__()")
class C(A):
def __init__(self):
A.__init__(self)
print("C.__init__()")
class D(B, C):
def __init__(self):
super(D, self).__init__()
print("D.__init__()")
D()
Run Code Online (Sandbox Code Playgroud) python multiple-inheritance super diamond-problem python-3.x
class A(object):
def __init__(self, a, b, c):
#super(A, self).__init__()
super(self.__class__, self).__init__()
class B(A):
def __init__(self, b, c):
print super(B, self)
print super(self.__class__, self)
#super(B, self).__init__(1, b, c)
super(self.__class__, self).__init__(1, b, c)
class C(B):
def __init__(self, c):
#super(C, self).__init__(2, c)
super(self.__class__, self).__init__(2, c)
C(3)
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,注释掉的__init__
调用看起来是进行超类初始化的普遍接受的"智能"方式.但是,如果类层次结构可能会发生变化,我一直在使用未注释的表单,直到最近.
看来,在B
上面层次结构中对超级构造函数的B.__init__
调用,再次调用,self.__class__
实际上C
并不B
像我一直假设的那样.
在Python-2.x中是否有某些方法可以在调用超级构造函数时保持正确的MRO(关于以正确的顺序初始化所有父类),而不是命名当前类(B
in in super(B, self).__init__(1, b, c)
)?
In [5]: class a(object):
...: def __init__(self):
...: print "In class a"
...: self.a = 1
...:
In [6]: class b(object):
...: def __init__(self):
...: print "In class b"
...: self.b = 2
...:
...:
In [7]: class c(b, a):
...: pass
...:
In [8]: c.mro()
Out[8]:
[<class '__main__.c'>,
<class '__main__.b'>,
<class '__main__.a'>,
<type 'object'>]
In [9]: obj = c()
In class b
In [10]: obj.__dict__
Out[10]: {'b': 2}
Run Code Online (Sandbox Code Playgroud)
__init__
类的默认方法c
在obj
创建时调用,它在内部调用__init__
仅类b
.
根据我的理解,如果我从2类继承,我的派生类对象应该具有来自两个类的变量(除非它们对这些类是私有的). …
可能重复:
了解Python super()
类的B
子类A
,所以在B中__init__
我们应该__init__
像这样调用A :
class B(A):
def __init__(self):
A.__init__(self)
Run Code Online (Sandbox Code Playgroud)
但是super()
,我看到这样的事情:
class B(A):
def __init__(self):
super(B, self).__init__() #or super().__init__()
Run Code Online (Sandbox Code Playgroud)
我的问题是:
为什么不super(B, self).__init__(self)
呢?仅仅因为返回代理对象是绑定的?
如果我在super中省略第二个参数并且返回代理对象是未绑定的,那么我应该写super(B).__init__(self)
吗?
我正在查看钻石问题并得到一个问题:
class A:
def __init__(self):
print("This is class A")
class B(A):
def __init__(self):
print("This is class B")
super().__init__()
class C(A):
def __init__(self):
print("This is class C")
super().__init__()
class D(B, C):
def __init__(self):
print("This is class D")
super().__init__()
i = D()
Run Code Online (Sandbox Code Playgroud)
This is class D
This is class B
This is class C
This is class A
Run Code Online (Sandbox Code Playgroud)
它按预期工作,这很好,但我想知道为什么super().__init__()
inclass B
不去class A
而是 C 被调用。
如果一个类有一个 super() 并且它继承自一个父类,它应该去那里。
如果我在 B 上删除它,代码将不会到达 C 或 A。
我知道 MRO 以及它是如何按预期进行的:
>>> …
Run Code Online (Sandbox Code Playgroud) python ×7
super ×4
python-3.x ×3
class ×1
constructor ×1
migration ×1
python-2.x ×1
python-2to3 ×1