我爱吃爆米花 发表于 2021-3-25 13:43:04

__init__和__new__魔法方法的疑惑?

《零基础入门pyhton》课程第41讲,测试题答案中:

1. 类实例化对象所调用的第一个方法是什么?
答:__new__ 是在一个对象实例化的时候所调用的第一个方法

2. 什么时候我们需要在类中明确写出 __init__ 方法?
答:当我们的实例对象需要有明确的初始化步骤的时候,你可以在 __init__ 方法中部署初始化的代码。
举个例子:
# 我们定义一个矩形类,需要长和宽两个参数,拥有计算周长和面积两个方法。
# 我们需要对象在初始化的时候拥有“长”和“宽”两个参数,因此我们需要重写__init__方法
# 因为我们说过,__init__方法是类在实例化成对象的时候首先会调用的一个方法,大家可以理解吗?
Question1:
对象实例化和实例化为对象这俩个概念有什么区别吗?
-----------------------------------------------------------------------------------------------
https://blog.csdn.net/Babysisterzh/article/details/54895351?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
概括:简言之,_new_作用于_init_之前。前者可以决定是否调用后者,或者说可以决定调用哪个类的_init_方法。
解释一:首先要知道在面向对象编程中,实例化基本遵循创建实例对象、初始化实例对象、最后返回实例对象这么一个过程。Python 中的 _new_ 方法负责创建一个实例对象,_init_ 方法负责将该实例对象进行初始化;​
解释二:有人说如果将类比喻为工厂,那么_init_方法则是该工厂的生产工人,_init_方法接受的初始化参数则是生产所需原料,_init_方法会按照方法中的语句负责将原料加工成实例以供工厂出货。而_new_则是生产部经理,_new_方法可以决定是否将原料提供给该生产部工人,同时它还决定着出货产品是否为该生产部的产品,因为这名经理可以借该工厂的名义向客户出售完全不是该工厂的产品
————————————————
版权声明:本文为CSDN博主「弓长张517」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Babysisterzh/article/details/54895351

Question2:
Python 中的 _new_ 方法负责创建一个实例对象,_init_ 方法负责将该实例对象进行初始化,这句话要怎么理解呢?








heidern0612 发表于 2021-3-25 16:22:00

本帖最后由 heidern0612 于 2021-3-25 16:28 编辑

Q1: 从语法的层面来说,我感觉这俩是一个意思....



Q2:从游戏的方面来讲,new的创建类似于你的角色槽,init创建则类似于你创建角色之后的各项属性,比如人物形象,人物种族和人物技能等。

你得首先有个角色槽,你才能创建你的角色,不然的话,哪来的空间给你创建呢?

也就是说,new的话定义了实例化具体的大方向属性。系统告诉你了,你要创建到底是个人还是个物品栏还是个仓库(大类别)。

而init的话,定义了你创建这个东西的属性(小类别),比如人物的话,你需要创建不同种族;物品的话,这个是补血的还是加buff的;仓库的话,是个人仓库还是工会仓库等。


所以咱们常见的new方法,一般都是改写了底层各类属性规则(如改写str或加减规则等),而init方法用于改写你创建的规则(如给你创建的实例赋予属性) 。

非要给两者分个区别的话,我个人感觉new方法类似神明创造了世界,而init类似人类创造了各项工具。


以上纯属个人见解。

笨鸟学飞 发表于 2021-3-25 16:42:06

class A():
    pass

a = A()
help(a.__init__())
运行上述代码得到:
Help on NoneType object:

class NoneType(object)
|Methods defined here:
|
|__bool__(self, /)
|      self != 0
|
|__repr__(self, /)
|      Return repr(self).
|
|----------------------------------------------------------------------
|Static methods defined here:
|
|__new__(*args, **kwargs) from builtins.type
|      Create and return a new object.See help(type) for accurate signature.

如果还不清楚,运行下面代码
class A(object):
    def __init__(self):# 无需返回值,参数是__new__返回的实例
      print('这是init方法-->', self)

    def __new__(cls):
      '''有返回值,参数是cls则表示是当前类实例
      如果是其他类的类名,那么实际创建返回的就是其他类的实例
      就不会调用当前类的__init__函数,也不会调用其他类的__init__函数'''
      print('这是cls的ID-->', id(cls))
      print('这是new方法-->', object.__new__(cls))
      return object.__new__(cls)

A()
print('这是类A的ID-->', id(A))

弈秋呜呜呜 发表于 2021-3-25 20:53:17

本帖最后由 弈秋呜呜呜 于 2021-3-25 20:55 编辑

Q1:我认为是一个意思
Q2:__new__(开辟空间。先要有空间,才有地方存放属性方法等) -----> __init__(初始化。为对象的属性赋值) -------> 对象
class A:
    def __new__(cls):
      print("我是new,我被调用了")
      return super().__new__(cls)
    def __init__(self):
      print("我是init,我被调用了")

a = A()
我是new,我被调用了
我是init,我被调用了
页: [1]
查看完整版本: __init__和__new__魔法方法的疑惑?