一切皆对象!!!
题主已经知道new能创建对象,那么想必应该也知道 () 这个操作符代表什么意思,他是去调用call方法,那么如何去判断一个对象有没有call方法
答案是
callable
下面看下Python代码
def test1():
pass
class Test2():
pass
print(callable(int))
print(callable(dict))
print(callable(test1))
print(callable(Test2))
上面的例子都是返回True,证明他们都是支持()这个操作的,也就是都有callable方法
再来看下元类type
callable(type)
毋庸置疑,这个也是True
所以正常的逻辑是
在解释器初始化的时候,调用type的call方法生成了class, 在程序实例化的时候,调用type的call方法生成了实例
!!!
很奇怪是不是,怎么都是type的call方法
这里就要说明下,type的type是什么?是type!!!
注意,这里不是调用自己的call方法,是调用上一级的call方法, 只不过上一级还是type
是不是打破了你的认识,这里跟new和init方法没有一点点关系,全是call方法再起作用
下面给出验证例子
class MyType(type):
def __init__(self, *args, **kwargs):
print('MyType __init__方法执行了', args, kwargs)
super(MyType, self).__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
print('MyType __new__方法执行了', args, kwargs)
return type.__new__(cls, *args, **kwargs)
def __call__(self, *args, **kwargs):
print('MyType __call__方法执行了', args, kwargs)
return super(MyType, self).__call__(*args, **kwargs)
class MyClass(metaclass=MyType):
def __init__(self, *args, **kwargs):
print('MyClass __init__方法执行了', args, kwargs)
super(MyClass, self).__init__(*args, **kwargs)
def __new__(cls, *args, **kwargs):
print('MyClass __new__方法执行了', args, kwargs)
return object.__new__(cls, *args, **kwargs)
def __call__(self, *args, **kwargs):
print('MyClass __call__方法执行了', args, kwargs)
print('=======运行前输出=======')
MyClass()
输出结果如下
MyType __new__方法执行了 ('MyClass', (), {'__module__': '__main__', '__qualname__': 'MyClass', '__init__': , '__new__': , '__call__': , '__classcell__': }) {}
MyType __init__方法执行了 ('MyClass', (), {'__module__': '__main__', '__qualname__': 'MyClass', '__init__': , '__new__': , '__call__': , '__classcell__': }) {}
=======运行前输出=======
MyType __call__方法执行了 () {}
MyClass __new__方法执行了 () {}
MyClass __init__方法执行了 () {}
是不是,在MyClass实例化的时候调用了上一级MyType的call方法
如果你想调用MyClass的call方法,得这样MyClass()()
为什么第一行少了type呢,因为第一次调用的是type的call方法,这里没办法重写,所以没有任何输出,而后续的就是调用的MyType的call方法,就有输出了
可是上面明明跟new init有关系啊,他们明确的执行了,跟上面说的不一样,其实这里可以大胆一点,猜测new和init方法都是在call方法里面执行的!!!
接下来到了查看type的call方法了。
一下代码摘自Python3.7.0源码 typeobject.c
static PyObject *
type_call(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
PyObject *obj;
if (type->tp_new == NULL) {
PyErr_Format(PyExc_TypeError,
"cannot create '%.100s' instances",
type->tp_name);
return NULL;
}
obj = type->tp_new(type, args, kwds);
obj = _Py_CheckFunctionResult((PyObject*)type, obj, NULL);
if (obj == NULL)
return NULL;
/* Ugly exception: when the call was type(something),
don't call tp_init on the result. */
if (type == &PyType_Type &&
PyTuple_Check(args) && PyTuple_GET_SIZE(args) == 1 &&
(kwds == NULL ||
(PyDict_Check(kwds) && PyDict_GET_SIZE(kwds) == 0)))
return obj;
/* If the returned object is not an instance of type,
it won't be initialized. */
if (!PyType_IsSubtype(Py_TYPE(obj), type))
return obj;
type = Py_TYPE(obj);
if (type->tp_init != NULL) {
int res = type->tp_init(obj, args, kwds);
}
return obj;
}
果然,里面有tpnew 和 tp_init方法,验证了我们的猜测。