Python “super()”在“new”中是什么意思__`

Python “super()”在“new”中是什么意思__`,python,python-3.x,Python,Python 3.x,注意:是Python flyweight实现的一部分 导入weakref 类别CarModel: _models=weakref.weakValue字典() 定义新(cls,型号名称,*args,**kwargs): model=cls.\u models.get(model\u name) 如果不是型号: 模型=超级() cls._models[model_name]=model 回归模型 def uuu init uuuu(self,model_name,air=False): 如果不是ha

注意:是Python flyweight实现的一部分

导入weakref
类别CarModel:
_models=weakref.weakValue字典()
定义新(cls,型号名称,*args,**kwargs):
model=cls.\u models.get(model\u name)
如果不是型号:
模型=超级()
cls._models[model_name]=model
回归模型
def uuu init uuuu(self,model_name,air=False):
如果不是hasattr(self,“initted”):
self.model\u name=model\u name
self.air=空气
self.initted=True
问题1>什么是
super()
意思?它是否意味着
CarModel
的父类

问题2>我也很难理解函数
\uu new\uu
是如何工作的?具体来说,下面一行

model = super().__new__(cls)
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

构造函数被称为
\uuuu new\uuuu
,与
\uuuu init\uuuu
相反,并且 只接受一个参数,即正在构造的类(它 在构造对象之前调用,因此不存在自我 参数)。它还必须返回新创建的对象

super()
用于引用超类(即从中生成子类的父类)


\uuuuuuuuuuuuuuuuuuuuuuuuuu是一个方法,如果类已定义,则调用该方法来创建该类的新实例。

我相信,您使用的是Python3,其中super不需要提供相同的类名。Super引用当前类的基类,并为您从正确的基类调用方法做适当的调整
\uuuu new\uuuu
是用于创建实例的方法。它是以
super()开头的。

本身就是
super(A,B)
的简写,其中
A
是代码出现的类,
B
是代码出现的函数的第一个参数;因此,在您的特定情况下,
super()。\uuuuu new\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

反过来,
super(T,O)
返回一个“super对象”。要了解超级对象的功能,您需要了解Python中实例和类上的属性引用是如何工作的

假设不涉及
\uuuuu getattr\uuuuuu
\uuuuuu getattribute\uuuuuu
方法,在对象
O
上引用属性
A
(即,评估
O.A
)继续执行以下步骤:

  • 如果在
    O
    的实例dict(
    O.\uuuu dict\uuuu
    中定义了
    “A”
    ),则直接返回该dict上的值,精确地返回原样
  • 否则,依次检查
    O
    方法解析顺序中的每个类,在每个dict中查找
    “A”
    。如果找到,调用值
    D
  • 如果
    D
    没有定义
    \uuuu get\uuuu
    ,则返回原样。但是,如果是这样,则
    D
    被称为“描述符”,其
    \uuu get\uuu
    方法被调用,其中
    O
    作为第一个参数,而
    type(O)
    作为第二个参数
  • 类上的属性引用的作用大致相同,将引用的类替换为实例,但有以下区别:

    • 步骤1不适用
    • 调用
      \uuuu get\uuu
      方法时,将
      None
      作为第一个参数,将引用的类作为第二个参数
    Python使用描述符来实现实例方法、类方法、静态方法和属性等

    然后,使用
    super(T,O)
    创建的超级对象是一个(内置)对象,该对象具有
    \uuuu getattribute\uuuuu
    方法,该方法在其上的每个属性引用上被调用,并在
    O
    的MRO中T之后的唯一类的dict中查找属性。然后,它会像往常一样调用
    \uuuu get\uuu
    打开它找到的值

    这个过程有点复杂,所以作为一个例子,下面是它在您的具体案例中的工作方式。由于
    CarModel
    是按原样定义的,因此其MRO是
    [CarModel,object]

  • super()
  • super(CarModel,cls)
    被计算以产生一个超级对象
    S
  • Python在
    S
    上获取属性
    “\uuuuu new”
    (相当于在Python代码中调用
    getattr(S,“\uuu new””
  • 由于
    S
    是在
    CarModel
    类上创建的,因此它在
    CarModel
    的MRO中考虑
    CarModel
    之后的类,并在
    对象本身的dict中查找
    “\uuuu new\uuuuuuuu”
    。它的值是一个静态方法,有一个
    \uuuu get\uuuu
    方法,该方法用参数
    None
    cls
    调用。由于
    \uuuuuu new\uuuuu
    是一个静态方法,因此它的
    \uuuuuu get\uuuuuuuu
    方法只返回未经修改的函数。因此,
    super(CarModel,cls)。\uuuu new\uuuu
    对象完全相同
  • 使用
    cls
    参数调用在最后一步中获得的函数(即
    object.\uuuu new\uuuu
    ),其中
    cls
    可能是
    CarModel
    ,最后是
    CarModel
    类的新实例
  • 我希望这是可以理解的

    (为了完整起见,应该提到的是,
    对象
    类上的实际
    \uuuuuuuuuu新
    函数实际上不是一个静态方法,而是一个特殊的内置函数,它根本没有
    \uuuuuu get\uuuuuuuuuuu
    方法,但是由于静态方法上的
    \uuuu get\uuuuuuuuuuuuu
    方法只是返回它们所定义的函数。)定义为,效果相同。)

    @Ben,基于t