鱼C论坛

 找回密码
 立即注册
查看: 952|回复: 6

[已解决]求助;关于init 方法的问题

[复制链接]
发表于 2018-5-21 23:09:50 | 显示全部楼层 |阅读模式
4鱼币
本帖最后由 xue11 于 2018-5-21 23:11 编辑

整体对init方法很不懂,对self.name = name很迷茫

问题1: 这个init构造方法到底有什么用途啊,小甲鱼老师说“重写init方法,可以定义对象的初始化操作"是什么意思,这个构造方法构造了什么?”重写init方法“是什么意思,难道不写上类代码中上也会调用吗?

例如:Class Bird():
                def __init__(self):
                        self.name='小鸟'

这个例子算重写了init方法,这可以理解为重写吗?要是没有写init这个方法,这个Bird()类会调用init吗,感觉不会,

问题2:init方法传入参数是怎么情况,根据小甲鱼老师的写的代码,传入的参数就是变量(属性)啊,例如图片的代码(见图片),是否可以理解为init方法就是重写”属性“的?


例2:class Ball:
                def __init__(self , name):
                                self.name = name
                def kick(self):
                        print('我叫%s,该死的,谁踢我,.....' % self.name)

问题3:这里没有明白为什么写成‘self.name = name’ ,为什么要这么写?

例3:class Ball:
        def __init__(seif ,name):
                pass       
        def kick(self):
                print('我叫%S,该死的,谁踢我,.....' % self.name)
问题4:如改成例3这样为什么会报错?
>>> b = Ball('小甲鱼')
>>> b.kick()
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    b.kick()
  File "C:\Users\songyuxue\Desktop\新建文本文档 (2).py", line 5, in kick
    print('我叫%S,该死的,谁踢我,.....' % self.name)
AttributeError: 'Ball' object has no attribute 'name'


222.JPG
最佳答案
2018-5-21 23:09:51
问题1: 这个init构造方法到底有什么用途啊,小甲鱼老师说“重写init方法,可以定义对象的初始化操作"是什么意思,这个构造方法构造了什么?”重写init方法“是什么意思,难道不写上类代码中上也会调用吗?

即使在类Bird中不写 __init__() 方法,它也会被调用。所有类继承自object,object含有各种魔法方法。
老师说的 '重写init方法,可以定义对象的初始化操作' , 目前可以简单理解为:实例化对象 初始化时,自动生成其属性。比如:bird = Bird(), 实例化对象bird生成时,自带属性name 且 其值为 '小鸟'。如果你不写__init__() 、方法中也不定义需要的属性, 实例化对象bird生成时,没有自己定义的属性。


问题2:init方法传入参数是怎么情况,根据小甲鱼老师的写的代码,传入的参数就是变量(属性)啊,例如图片的代码(见图片),是否可以理解为init方法就是重写”属性“的?

比如: ball = Ball('football') ,这样就是 生成实例化对象ball时,传入参数 'football',用以给实例化对象ball的属性name赋值(使name='football')。通过__init__方法,可以给定义的实例化属性赋值


例2:class Ball:
                def __init__(self , name):
                                self.name = name
                def kick(self):
                        print('我叫%s,该死的,谁踢我,.....' % self.name)

问题3:这里没有明白为什么写成‘self.name = name’ ,为什么要这么写?

你的属性名是 self.name , 参数名为 name , 将传入的参数值 赋值给属性:self.name = name

例3:class Ball:
        def __init__(seif ,name):
                pass        
        def kick(self):
                print('我叫%S,该死的,谁踢我,.....' % self.name)
问题4:如改成例3这样为什么会报错?

因为,在__init__()中定义了两个参数:self,name, 实例化对象时 b = Ball('小甲鱼') :b就是参数self、name是'小甲鱼' ,但是没有写self.name属性、 self.name就不会被赋值,因此报错:'Ball' object has no attribute 'name'  对象没有name属性

最佳答案

查看完整内容

问题1: 这个init构造方法到底有什么用途啊,小甲鱼老师说“重写init方法,可以定义对象的初始化操作"是什么意思,这个构造方法构造了什么?”重写init方法“是什么意思,难道不写上类代码中上也会调用吗? 即使在类Bird中不写 __init__() 方法,它也会被调用。所有类继承自object,object含有各种魔法方法。 老师说的 '重写init方法,可以定义对象的初始化操作' , 目前可以简单理解为:实例化对象 初始化时,自动生成其属性。 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-5-21 23:09:51 | 显示全部楼层    本楼为最佳答案   
问题1: 这个init构造方法到底有什么用途啊,小甲鱼老师说“重写init方法,可以定义对象的初始化操作"是什么意思,这个构造方法构造了什么?”重写init方法“是什么意思,难道不写上类代码中上也会调用吗?

即使在类Bird中不写 __init__() 方法,它也会被调用。所有类继承自object,object含有各种魔法方法。
老师说的 '重写init方法,可以定义对象的初始化操作' , 目前可以简单理解为:实例化对象 初始化时,自动生成其属性。比如:bird = Bird(), 实例化对象bird生成时,自带属性name 且 其值为 '小鸟'。如果你不写__init__() 、方法中也不定义需要的属性, 实例化对象bird生成时,没有自己定义的属性。


问题2:init方法传入参数是怎么情况,根据小甲鱼老师的写的代码,传入的参数就是变量(属性)啊,例如图片的代码(见图片),是否可以理解为init方法就是重写”属性“的?

比如: ball = Ball('football') ,这样就是 生成实例化对象ball时,传入参数 'football',用以给实例化对象ball的属性name赋值(使name='football')。通过__init__方法,可以给定义的实例化属性赋值


例2:class Ball:
                def __init__(self , name):
                                self.name = name
                def kick(self):
                        print('我叫%s,该死的,谁踢我,.....' % self.name)

问题3:这里没有明白为什么写成‘self.name = name’ ,为什么要这么写?

你的属性名是 self.name , 参数名为 name , 将传入的参数值 赋值给属性:self.name = name

例3:class Ball:
        def __init__(seif ,name):
                pass        
        def kick(self):
                print('我叫%S,该死的,谁踢我,.....' % self.name)
问题4:如改成例3这样为什么会报错?

因为,在__init__()中定义了两个参数:self,name, 实例化对象时 b = Ball('小甲鱼') :b就是参数self、name是'小甲鱼' ,但是没有写self.name属性、 self.name就不会被赋值,因此报错:'Ball' object has no attribute 'name'  对象没有name属性
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-5-21 23:28:37 | 显示全部楼层
本帖最后由 ABC23 于 2018-5-22 11:48 编辑

init方法是Python的初始化方法,Bird类隐式继承自object,在构造对象时,调用父类的__new__方法,[del]如果子类不写__init__方法,是不会自动调用的。[/del]

突发奇想,可以用英语的"the"和"a"来解释:"the"表示“特指”,具体指某一个或某一类具有特定性质的事物,而“a”表示泛指。
class Demo:
        def __init__(self, name):
                self.name = name

self表示特指,相当于“the”。
右边的name为泛指,只要你具有name属性,你就被称作那个啥(跟我念“a name”)。

比方说:self =>绑定=> 变量a,self =>绑定=>变量b
             name = "joy", name = "bitch"。。

=================

勘误:上面我写错了。如果继承的子类不重写__init__方法,是会自动调用父类的__init__方法的。

栗子:

>>> class Father:
        def __new__(cls):
                print('Father: __new__')
                return super().__new__(cls)
        def __init__(self):
                print('Father: __init__')

               
>>> class Adoptedchild(Father):
        pass

>>> class Fakechild(Father):
        def __new__(cls):
                print('Fakechild: __new__')
                return super().__new__(cls)
        def __init(self):
                print('Fakechild: __init__')

               
>>> class Son(Father):
        def __new__(cls):
                print('Son: __new__')
                return super().__new__(cls)

       
>>> class Daughter(Father):
        def __init__(self):
                print('Daughter: __init__')

               
>>> obj = object()
>>> father = Father()
Father: __new__
Father: __init__
>>> adoptedchild = Adoptedchild()
Father: __new__
Father: __init__
>>> fakechild = Fakechild()
Fakechild: __new__
Father: __new__
Father: __init__
>>> son = Son()
Son: __new__
Father: __new__
Father: __init__
>>> daughter = Daughter()
Father: __new__
Daughter: __init__


总结起来就是,1. __new__方法不管有没有重写,都会调用父类的__new__方法来构造子类;2. 如果子类重写了__init__方法,调用子类自己的__init__方法,否则自动调用父类的初始化方法。理解起来,在__new__方法中显式调用super(),而在init方法中处于某种考虑可以不写super()调用。当然在实际运用中,为了保持父类和子类的连贯性,还是在子类__init__方法中显式调用super(),虽然这不是必须的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-5-21 23:39:37 | 显示全部楼层
1,__init__ 方法一般会在初始化实例对象时调用,不管你重写与否,该方法都会调用,因为你不重写的话,也是存在的。。可以这样理解,python中所有的类都会直接或间接的继承自object,而object中已经定义了很多魔法方法,如果我们想自定义的话,就重写,不想重写的话,就会默认调用父类中的方法,传入本类的对象(self)。。。一般在__init__中初始化对象属性,便于代码维护
回答你的问题:这个算重写,即使你不写,也会调用父类中的__init__方法
2,其实执行到__init__时,self对象已经初始化了,此时不仅可以初始化self的属性,还可以调用self中的对象方法
3,self.name就是属性定义,同时做初始化赋值,这样就可以在其他方法中使用self.name,否则会提示属性不存在
4,self.name不存在。。。print上边添加一行 self.name = "xxx" 就可以了,属性初始化可以在任何地方,但放在__init__中比较规范,便于统一维护

评分

参与人数 1鱼币 +1 收起 理由
xue11 + 1

查看全部评分

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-5-22 21:10:36 | 显示全部楼层
thexiosi 发表于 2018-5-22 08:55
问题1: 这个init构造方法到底有什么用途啊,小甲鱼老师说“重写init方法,可以定义对象的初始化操作"是什 ...

class Ball:
        def __init__(self , name):
                        self.names = name
        def kick(self):
                print('我叫%s,该死的,谁踢我,.....' % self.name)

为什么这样也会报错,难道self后面跟的必须是参数name 吗?
>>> b = Ball('小甲鱼')
>>> b.kick()
Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    b.kick()
  File "C:\Users\songyuxue\Desktop\新建文本文档 (2).py", line 5, in kick
    print('我叫%s,该死的,谁踢我,.....' % self.name)
AttributeError: 'Ball' object has no attribute 'name'
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-5-22 21:28:19 | 显示全部楼层
你定义的属性是 self.names,但是 使用的是 self.name
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2018-5-22 21:40:54 | 显示全部楼层
thexiosi 发表于 2018-5-22 21:28
你定义的属性是 self.names,但是 使用的是 self.name

感谢!!明白了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-25 10:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表