暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Python快速入门(六)

Python学会 2019-09-11
265


引言


Python作为一个,目前最火的编程语言之一,已经渗透到了各行各业。它易学好懂,拥有着丰富的库,功能齐全。人生苦短,就用Python。


这个快速入门系列分为六篇,包含了Python大部分基础知识,每篇阅读时间不长,但内容含量高。大家最好亲自码一遍代码,这样可以更有收获。



概要


1、掌握Python中对象和类,感受面向对象编程。

2、掌握Python中类的继承,了解两种基本继承方式;

3、掌握Python中类的合并,为实际应用做好铺垫。



类和对象


Python是一个面向对象(object)的编程语言,当然这个对象不是那个对象。在Python中创建一个类(class)和对象是很容易的。我们先铺垫一些概念,大家初次见到不理解没有关系,随着编写代码,我们会一步步理解这些概念。


类(class),顾名思义,它代表一“类”对象,比如学生是一个“类”,具体而言,学生这个类里面可以有学生的姓名,身高,体重,性别等信息。这和我们之前学习的字典有些类似。具体而言,张三可以是学生这个类(class)的实例,李四也可以。那么我们把“张三”和“李四”叫做学生类的实例,也就是对象。

代码:

class Student(object):

    def __init__(self,id,name):

        self.id = id

        self.name = name

    def infor(self):

        print (self)

        print  ('The name is %s and the id is %s' % (self.name, self.id) ) 


Harry = Student('1212','Harry Potter')

Harry.infor()


讲解:

我们建立了一个叫做Student的类,这里首行用冒号结尾以及此行缩进和函数,条件和循环形式是一样的。类里面有两个函数,第一个函数__init__()是每一个类的标配,负责初始化类中的固定元素。比如对一个学生,其固有属性包括了学生的学号(id)以及学生的名字(name)。其中self变量起到的作用就是记录和传递我们定义的两个属性id和name。第二个函数,大家比较熟悉了,目的是打印出来学生的姓名和学号,这个函数接收在__init__()中定义好的self,然后把其中的信息打印出来。

运行结果:

The name is Harry Potter and the id is 1212



概念和解释


结合上面的代码,我们给与一些常见概念的解释:


  • 对象(object):通过类定义的数据结构实例。这个概念根植于类的数据以及其实例化,比较抽象,大家可以在学习的过程中慢慢思考。

  • 实例化(instance):创建一个类的实例,类的具体对象。就像我们在第一节中定义了Student这个类,而给Harry同学建立一个Student的类,就是一个实例化操作。

  • def:在类里边定义函数的方法。这个同我们一般意义上定义函数是一样的。

  • self:指被访问的对象或者实例的一个变量。Self作为类中的一个独特存在,代表类的实例,用于存储类中的数据和方法。


练习题:

1,在__init__()中加入一个print(self),看看它是什么时候会被执行,以及执行结果。

2,在infor(self)中加入一个print(self),看看它是什么时候会被执行,以及执行结果。

3,定义一个关于水果的类,里面存储水果的颜色,价格等等,并用具体的水果实例化。


类的继承


类的从属关系


在上一课我们介绍了类和对象。这里我们通过两个类同时存在的例子出发,让大家对类和对象有一个更加清晰的认识。


假如我问你香蕉和水果有什么区别,你肯定会说香蕉是水果的一种,而水果包含了香蕉。没错,你肯定能看出来水果就是我们代码中的类(class),而香蕉是水果的一个实例(instance),同时香蕉也因为是水果的实例,所以它是一个对象(object)。恭喜你,已经参透了类和对象的第一层关系。


接下来,我会问题你,香蕉和仙人蕉有什么关系呢?事实上,仙人蕉是香蕉的一种,也就是说仙人蕉是香蕉这个类的实例化。说到这里,我们不难发现,水果是一个类,香蕉也是一个类,然而这并不矛盾。我们可以用从属关系来区分它们:香蕉是一种水果而仙人蕉是一种香蕉。下面看具体的例子:


代码:

class Fruit(object):

    def __init__(self,name):

        self.name = name

        self.color = None


class Banana(Fruit):

    def __init__(self,name,price):

        super(Banana, self).__init__(name)

        self.price = price

        

Canna = Banana('canna',15)

print (Canna.name, Canna.price)

print (Canna.color)

Canna.color = 'yellow'

print (Canna.color)


讲解:

这个例子中出现了一些大家可能陌生的代码,先撇开没见过的代码来分析一下。对于第一个类Fruit,我们知道Fruit有name和color;对于第二个类,Banana是一种Fruit,而Banana有name和price这两种属性。到此为止我们初步理清楚了上面代码中两个类之间的关系,通过打印不难发现,Canna(仙人蕉)将Banana这个类实例化,且给Banana的两种属性,名字和价格赋值。

运行结果:

canna 15

None

yellow


眼尖的同学们肯定发现了上面的代码中有两处奇怪的地方,一处是Fruit类中的self.color=None,而另外一处是很陌生的super函数。我们给大家一一解释:


  • None在这里相当于空的意思,也就是说我们虽然定义了Fruit这个类,并且让其有一个color属性,但是我们并不想直接实例化这个类,所以就让color在__init__()函数中保持空的状态。

  • 注意到我们在Banana类里面用super函数来继承上一个类,也就是Fruit的name和color属性。也就是说Banana继承Fruit后是有name和color这个属性的。



几种继承方式


当我们用class Banana(Fruit) 的时候已经开始了继承,即让Banana去继承Fruit这个类。继承意味着一个类(Banana)的大部分或者全部功能来自其父类(Fruit)。具体而言继承的方式有三种:


  • 隐式继承

  • 显式覆盖

  • 在运行前或运行后替换


我们重点介绍前两种继承方式:


代码·隐式继承

class Parent(object):

    def function(self):

        print ('Hello World')


class Child(Parent):

    pass

        

dad = Parent()

son = Child()

dad.function()

son.function()


讲解:

在上面的代码中,我们用pass创建空代码,也就是说在Child这个类中只继承Parent类而没有任何别的定义和操作,我们把这种继承方式叫做隐式继承。注意到上面的代码中我们在Child这个类当中没有定义带有打印功能的函数,它通过继承父类Parent中的打印函数来自动获得

运行结果

Hello World

Hello World


代码·显式覆盖:

class Parent(object):

    def function(self):

        print ('Hello World')


class Child(Parent):

    def function(self):

        print ('How old are you')

        

dad = Parent()

son = Child()

dad.function()

son.function()


讲解:

假想我们在子类中定义一个和父类同样的函数,会发生什么呢?答案是子类中的函数会覆盖来自于父类中的函数,也就是说子类用的函数是自己定义的,而非从父类中继承来的。当然我们这里的覆盖的意思不是把父类的函数也改变。这个代码中,我们给子类Child也定义了function,打印的内容换成了How old are you。于是我们将会看到两个类的实例出来的结果是不一样的。它通过继承父类Parent中的打印函数来自动获得。

运行结果:

Hello World

How old are you


类的合成


类的合成范式


和继承一样,合成可以让我们直接使用别的类里面的函数和方法。不同的是,类的合成并不会在子类中修改和覆盖父类的函数内容,可以避免混乱



代码:

class Other(object):

    def function(self):

        print ('Hello World')


class Child(object):

    def __init__(self):

        self.other = Other()

    def function(self):

        self.other.function()


son = Child()

son.function()


讲解:

在合成方法中,我们并不需要申明Child中的对象(object)是继承自父类Other。之所以用Other而不用Parent,是因为我们想区分和继承的差别。合成的关键代码就是self.other = Other(),有了这一行代码,下面的工作就很自然了。我们在Child类中,定义了一个function(),并在里面直接使用other.function(),从而达到了合成效果。

运行结果:

Hello World



类的合成举例


合成和用途十分广泛,比如我们拿最近很火的吃鸡游戏来举例。游戏里面有各种各样的枪械武器,每一种枪械都有其各自的属性,比如射程,穿透力啊之类的。最直接的想法是给枪建造一个类,里面存储了各种各样的属性,用来定义这种枪的各种属性。那如果一个玩家获得了这把枪,而且假设玩家也是一个类,那么如何处理这两个类之间的关系呢?答案就是用合成:


代码:

class Gun(object):

    def __init__(self):

        self.name = '98K'

        self.attack = 888

        

class Player(object):

    def __init__(self):

        self.weapon = Gun()


Jack = Player()

print (Jack.weapon.name)


讲解:

我们定义了一个Gun的类,它的名字是98K,为了方便起见,我们只给了它一个攻击力的属性,一枪888暴击伤害。然后在玩家类的武器weapon属性栏,我们通过self.weapon=Gun(),给他配备了这把枪。最后,我们实例化玩家,建立了一个名字叫Jack的玩家,打印这个玩家的武器名字,发现的确他拥有一把98K。

运行结果:

98K

你点的每个赞,我都认真当成了喜欢
文章转载自Python学会,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论