實例化過程Cpython過程等價為
def __call__(obj_type, *args, **kwargs):
obj = obj_type.__new__(*args, **kwargs)
if obj is not None and issubclass(obj, obj_type):
obj.__init__(*args, **kwargs)
return obj
假設(shè)有一個類Foo:
class Foo(object):
def __init__(self, x, y=0):
self.x = x
self.y = y
然后實例化
f = Foo(1, y=2)
執(zhí)行過程為
- Foo(*args, **kwargs) 首先調(diào)用 Foo.__call__(*args, **kwargs),如果沒有__call__則調(diào)用tp_call屬性(解釋器內(nèi)置,C語言)
- 因為 Foo 是object的子類,所以 Foo.__call__(*args, **kwargs) 調(diào)用的是 object.tp_call(Foo, *args,**kwargs)
- object.tp_call(Foo, *args, **kwargs) 調(diào)用的是 object.__new__(Foo, *args, **kwargs),然后返回了 obj
- obj 被 obj.__init__(*args, **kwargs) 初始化
- 最后 obj 就被返回了
同時,如果子類中未定義__init__,則父類的__init__方法會在子類的各屬性及方法初始化后再調(diào)用,例如先定義基類
import math
class Structure1:
# Class variable that specifies expected fields
_fields = []
def __init__(self, *args):
if len(args) != len(self._fields):
raise TypeError('Expected {} arguments'.format(len(self._fields)))
# Set the arguments
for name, value in zip(self._fields, args):
setattr(self, name, value)
然后使你的類繼承自這個基類
# Example class definitions
class Stock(Structure1):
_fields = ['name', 'shares', 'price']
class Point(Structure1):
_fields = ['x', 'y']
class Circle(Structure1):
_fields = ['radius']
def area(self):
return math.pi * self.radius ** 2
使用這些類的示例均實例化成功:
>>> s = Stock('ACME', 50, 91.1)
>>> p = Point(2, 3)
>>> c = Circle(4.5)
參考http://liuliqiang.info/post/understanding-python-class-instantiation
參考Stackoverflow
參考Python Cookbook