def __init__(self)和def __init__(self, 参数1,参数2,···,参数n)的用法详解

Jupyter Notebook
14 篇文章1 订阅
订阅专栏
python魔法方法的用法详解
def initnew方法
super用法详解
==def init(self)形式==
==def init(self, 参数1,参数2,···,参数n) 形式==
class类中init()函数及self参数解析
def initnew方法
方法 调用时间 功能
init 当实例对象创建之后被调用 用于设置对象属性的一些初始值
new 当实例对象创建之前被调用 用于创建实例然后返回该实例,是个静态方法
总结:

类中newinit方法的执行顺序如下:
1、首先,newinit之前被调用;
2、然后,new的返回值(实例)将传递给init方法的第一个参数;
3、然后,init给这个实例设置一些参数。
new方法的定义要求:
'''

定义父类A

class A(object): #
def new(cls,x): #至少要有一个参数cls,代表要实例化的类
print('this is in A.new,and x is ',x) # 描述性语句
return super(A,cls).new(cls)

定义子类B

class B(A):
def new(cls,z): #至少要有一个参数cls,代表要实例化的类
print('this is in B.new,and z is ',z) # 描述性语句
return object.new(cls) #返回object的new出来的实例
# 或者
return A.new(cls,z) #返回父类A的new出来的实例
'''
1、new至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供;
2、new必须要有返回值,返回实例化出来的实例,这点在自己实现new时要特别注意,可以return父类new出来的实例,或者直接是object的new出来的实例。

init方法的注意事项:
init有一个参数self,就是new返回的实例,initnew的基础上可以完成一些其它初始化的动作,init不需要返回值。

我们可以将类比作制造商,new方法就是前期的原材料购买环节,init方法就是在有原材料的基础上,加工,初始化商品环节。

self和super的区别:
1、self是首先调用自身的方法如果自身没有再去父类中找;super是直接从父类中找方法;
2、self是类,super是预编译指令;
3、self class 和super calss的输出是一样的;
4、super() 在类的继承里,实现父类多次被子类调用时只执行一次, 优化了执行逻辑;

super用法详解
定义类的基本范例:
'''
class Foo: #定义一个类
def bar(self,message): #定义类中的方法bar
print(message)

a=Foo() #定义变量a指向类Foo的实例化对象Foo()
a.bar("Hello") #变量a调用类Foo的方法bar(),"hello"为传递给形参“message”的实参
或者
Foo().bar("Hello,Python.") #避免定义变量a,直接对实例化对象调用类方法bar()

super在继承中的调用:
当存在继承关系时,若需要在子类中调用父类的方法,此时最简单的方法是:把对象调用转换成类调用,需要注意此时self参数需要显式传递。
典例如下——基础class继承的定义:

class FooParent: #定义父类FooParent
def bar(self,message): #定义父类的方法bar
print(message)
class FooChild(FooParent): #定义子类FooChild
def bar(self,message): #定义子类的方法bar
FooParent.bar(self,message) #方法一:在子类中直接调用父类的方法,此时需将“对象调用”转换为“类调用”
#或者
super(FooChild,self).bar(message) #方法二:直接调用super()机制
#此时self参数需要显式传递
FooChild().bar("Hello,Python.")

Hello,Python.
'''
上述实例的缺点如下:
(1)如果修改了父类名称,那么在子类中会涉及多处修改
(2)Python是允许多继承的语言,如上所示的方法在多继承时就需要重复写多次,显得累赘。
为了解决这些问题,Python引入了super()机制:

用super(FooChild, self).bar(message)方法,直接替换FooParent.bar(self, message)方法
最终结果是一致的,但实际上这两种方法的内部处理机制完全不同,当涉及多继承情况时,就会表现出明显差异。
在super机制里可以保证公共父类仅被执行一次,super机制的执行顺序是按照MRO(Method Resolution Order)方法解析顺序进行的。
典例如下——super机制下class继承的定义:
'''

子类直接显示调用父类的方法

class A: #定义父类A
def init(self): #定义父类A的初始化方法
print("Enter A")
print("Leave A")
class B(A): #定义继承子类B
def init(self):
print("Enter B")
A.init(self)
print("Leave B")
class C(A):
def init(self):
print("Enter C")
A.init(self)
print("Leave C")
class D(A):
def init(self):
print("Enter D")
A.init(self)
print("Leave D")
class E(B,C,D):
def init(self):
print("Enter E")
B.init(self)
C.init(self)
D.init(self)
print("Leave E")

E() # 实例化对象
#该方法的执行顺序很好理解,唯一需要注意的是公共父类A被执行了多次。

Enter E
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Enter D
Enter A
Leave A
Leave D
Leave E

子类使用super机制调用父类的方法

class A:
def init(self):
print("Enter A")
print("Leave A")
class B(A):
def init(self):
print("Enter B")
super(B,self).init()
print("Leave B")
class C(A):
def init(self):
print("Enter C")
super(C,self).init()
print("Leave C")
class D(A):
def init(self):
print("Enter D")
super(D,self).init()
print("Leave D")
class E(B,C,D):
def init(self):
print("Enter E")
super(E,self).init()
print("Leave E")

E() #实例化对象
#super机制可保证公共父类仅被执行一次,执行的顺序是按照MRO(Method Resolution Order)方法解析顺序进行的.

Enter E
Enter B
Enter C
Enter D
Enter A
Leave A
Leave D
Leave C
Leave B
Leave E
'''
def init(self)形式
这种形式在init方法中,只有一个self,指的是实例本身,包含两个属性,name, score。它允许定义一个空的结构,当新数据来时,可以直接添加。实例化时,需要实例化之后,再进行赋值。
'''
class Game:# 定义Game类
def init(self): #创建类中的函数,也叫方法
self.name=None #属性值为空
self.score=None #属性值为空

def print_score(self):
    print("%s score is %s"% (self.name,self.score))

s1=Game() #创建对象1
s1.name='Tom'
s1.score=8

s2=Game() #创建对象2
s2.name='Jerry'
s2.score=7

s1.print_score()
s2.print_score()

Tom score is 8 #输出结果
Jerry score is 7
'''
def init(self, 参数1,参数2,···,参数n) 形式
这种形式在定义方法时,就直接给定了两个参数name和score,且属性值不允许为空。实例化时,直接传入参数。
'''
class Game: #定义类Game
def init(self,name,score): #创建类中的函数,也叫方法
self.name=name #属性值不为空
self.score=score #属性值不为空
def print_score(self):
print("%s score is %s"% (self.name,self.score))
s1=Game("tom",8) #创建对象s1
s2=Game("Jerry",7) #创建对象s2
s1.print_score()
s2.print_score()

tom score is 8
Jerry score is 7
'''
总结:
1、self是形式参数,当执行s1 = Game(“Tom”, 8)时,self等于s1;当执行s2 = Game(“sunny”, 7)时,self=s2。
2、两种方法的区别在于定义函数时属性赋值是否允许为空和实例化时是否直接传入参数,个人觉得第二种更为简洁。

class类中init()函数及self参数解析
class类内容的基本组成:
(1)类属性:类中所涉及的变量
(2)类方法:类中的函数

2、init()函数解析
(1)双下划线开头的函数为私有函数,不能在类的外部被调用或直接访问;
(2)init(),支持带参数的初始化,例如:def init(self,ai_settings,screen):
(3)init()函数的第一个参数必须为self(也可是别的名字),后续参数可自由指定;

class中函数的定义
基本形式如下:

def 函数名(参数1,参数2....):
1
(1)在类的内部,使用def关键字定义一个函数必须包含参数self且必须为第一个参数,也可用**kw定义关键参数(表示任意参数)。
(2)self只有在类的方法中才会有,独立函数或者方法是不必须带self的,self名称不是必须的,是人们约定成俗的,self指的是类实例对象本身,而不是类本身。

不用init()方法定义类

定义一个矩形的类,目的是求周长和面积

'''
class Rectangle():
def getPeri(self,a,b):
return (a+b)2
def getArea(self,a,b):
return a
b

rect=Rectangle()
print(rect.getPeri(3,4))
print(rect.getArea(3,4))
print(rect.dict)

14
12
{}
'''
'''
class Rectangle():
def init(self,a,b):
self.a=a
self.b=b
def getPeri(self):
return (self.a + self.b)*2
def getArea(self):
return self.a * self.b

rect = Rectangle(3,4)
print(rect.getPeri())
print(rect.getArea())
print(rect.dict)

14
12
{'a': 3, 'b': 4}
'''
从上例中可以看到,我们在类中并没有定义init()方法,但是也能够得到类似的要求,结果返回了矩形实例rect的周长及面积。
但是,我们通过print(rect.dict)来看这个实例的属性,竟然是空的,我定义了一个矩形,按理来说它的属性应该是它的长、宽。但是它竟然没有。这就是没有定义init()的原因了。
并且,在实例化对象的时候,rect = Rectangle()参数为空,没有指定a、b的值,只有在调用函数的时候才指定了。且类中定义的每个方法的参数都有a、b,这显然浪费感情,在类中直接指定方法就可以了。、

因此吧,需要在类中定义init()方法,方便创建实例的时候,需要给实例绑定上属性,也方便类中的方法(函数)的定义。
定义完init()后,创建的每个实例都有自己的属性,也方便直接调用类中的函数。
————————————————
版权声明:本文为CSDN博主「Yale曼陀罗」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42782150/article/details/97132438

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容