构造方法——魔法方法1__init__()

构造方法也是函数,但是它调用的时间是确定的,当一个对象被创建之后,会立即调用构造方法。
原来我在写objective-c和C#时都会写构造方法,用来初始化类中属性。而且需要显示的调用。
Python中有一类魔法方法(特殊方法),初始化用到是init

class Person:
    def __init__(self):
        self.name = "nzh"
        self.age = 25


p1 = Person()
print("p1的姓名:{0},年龄:{1}".format(p1.name, p1.age))

image.png

init函数中,我们设定了两个属性,name和age。并且直接赋值。
在调用Person()函数时,它会隐式调用init()函数,然后Person类的对象中的属性就被设置了。
init()函数中默认会传递一个self的参数,self代表的是对象自己,那么生成p1对象时调用的Person()函数时,这个self就代表了p1,self会对当前对象进行绑定。

上面的例子我们是把属性值都定死了,这不够灵活。如果想让自定义属性的值,就需要给init()函数传递参数。

# 构造一个用户信息
class User:
    def __init__(self, name, age):
        self.name = name
        self.age = age

user1 = User("nzh", 25)
print("user1用户的名字:{0},年龄:{1}".format(user1.name, user1.age))

Python中有一个魔法方法叫del,相当于析构函数,它的作用是在被垃圾回收之前调用,但是发生的时间不可预知,应该尽力避免使用。

构造方法在继承中的使用

现在有两个类,A和B。B是A的子类。
A中定义了一个hello方法,B中没有定义任何内容,当B的对象调用hello方法时,同样可以调用。因为hello方法是从父类A中继承过来的。
这里面跟构造函数有很大关系,因为B的构造方法调用了A的构造方法,如果不是这样,B中就不能调用hello方法。

那么如何调用父类的构造方法?有两种方式。

调用未绑定的超类构造方法

在Python3.0之前会用到的方法,现在更流行用super函数,稍后说super,先说未绑定。

class Bird():
    def __init__(self):
        self.hungry = True

    def eat(self):
        if self.hungry == True:
            print("吃点东西...")
            self.hungry = False
        else:
            print("我不饿,谢谢")

class SongBird(Bird):
    def __init__(self):
        self.sound = "this is a song"

    def sing(self):
        print(self.sound)

s = SongBird()
s.sing()
s.eat()

image.png

这里SongBird类的对象不能调用eat方法,就是因为在SongBird初始化的时候没有调用超类的构造方法,可以修改SongBird的初始化函数init()

class SongBird(Bird):
    def __init__(self):
        Bird.__init__(self)
        self.sound = "this is a song"

    def sing(self):
        print(self.sound)

加了一句Bird.init(self)就能调用了Bird类中的eat方法了?背后发生了一些事情。
在调用一个实例的方法时,该方法的self参数会被自动绑定到实例上(这叫绑定方法)。如果只是调用Bird.init(),而没有给它传递self参数,那么Bird也不知道绑定了哪个实例,而且会引发一个TypeError错误。

image.png

正如上图所示,错误信息显示init()方法少了一个必要的参数self。
如果直接调用Bird类的Bird.init呢?(看起来像是一个属性,而非方法)
image.png

同样可以看到,提示没有hungry属性,没有提供self参数,实例就不会被绑定,这样就可以随便提供self参数。
例子中是吧SongBird的self传给了Bird的init函数(不知道这么理解对不对),这种方法就是未绑定方法(unbound)

使用super函数

首先得知道super函数只能在新式类中使用,如果你使用过老版本的python那么就不行了。至少是2.2以后,因为super是2.2新加入的特性。
修改SongBird类:

class SongBird(Bird):
    def __init__(self):
        super(SongBird, self).__init__()
        self.sound = "this is a song"

    def sing(self):
        print(self.sound)

为什么一个super就解决了这些问题呢?其实super函数很只能,不管你的这个类继承了多少层超类,它只需要使用一次super函数就可以调用超类中的方法,前提是这些超类中都要使用super函数。
super函数返回的是一个super对象,它负责对调用的方法进行解析,以至于我们可以成功调用超类中的方法。
有多层继承关系时,子类从下至上逐层寻找,比如D是C的子类,C是B的子类,B是A的子类。
那么继承关系就是这样的A->B->C->D。
D中先到C中找,如果C中没有该方法,再去B中找,最后再去A中找。找不到会报错,异常类型为AttributeError。

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

推荐阅读更多精彩内容