当我们上课时会发生什么?

时间:2020-05-09 14:04:46

标签: python object

简而言之,从python

如果C是一个类,则语句x=C(23)等效于:

x = C.__new__(C, 23) 
if isinstance(x, C): type(x).__init__(x, 23)

根据我的理解,object.__new__创建了一个新的,未初始化的类实例,该实例将其作为第一个参数。

为什么需要对isinstance()进行检查。 __new__是否返回类型为C的对象,这不是很明显。

如果此测试失败会发生什么情况?

由于classescallables,所以对__new__的调用是在类的__call()__方法中完成的

我在这里缺少什么吗,请给我澄清一下

2 个答案:

答案 0 :(得分:2)

__new__是否会返回类型为C的对象不是很明显。

一点也不。以下是有效的:

>>> class C:
...   def __new__(cls):
...     return "not a C"
...   def __init__(self):
...     print("Never called")
...
>>> C()
'not a C'

当您覆盖__new__时,您将可能返回一个cls的实例,但是并不需要 。这对于定义工厂类很有用,工厂类不会创建自身的实例,而是创建其他类的实例。

请注意,您引用的信息不太准确。第一步,x = C(32)等效于x = type.__call__(C, 32)。是type.__call__调用C.__new__,然后决定是否调用返回值的__init__方法。

您可以将type.__call__定义为类似

def __call__(cls, *args, **kwargs):
    obj = cls.__new__(cls, *args, **kwargs)
    if isinstance(obj, cls):
        obj.__init__(*args, **kwargs)
    return obj

将其应用于C,我们看到obj设置为str'not a C',而不是C的实例,所以{ 1}}在返回字符串之前不会被调用。

答案 1 :(得分:0)

isinstance(a, b)用于检查a是否为b的实例。不知道为什么创建后要检查它。魔术方法可以重新定义。尽管在正常情况下,需要isinstance()来检查动态数据。