返回宝典

类与对象

上一节 下一节

之前说的整型、浮点型、字符串类型、列表等类型都是python的标准类,其实还可以自定义一个类型。开发者可以先自定义一个类,预设好特定的属性和方法;然后可以根据这个自定义的类来创建实例对象。有种造物者的感觉,造物者创造了不同的生物种类,比如有一种生物叫Zombie(僵尸),Zombie就是一个类,而每一只具体的僵尸,则是根据Zombie这个类而创造出来的实例对象。这就是所谓的面向对象编程


类 - 属性

举一个例子,来创建一种代表僵尸的类,就叫Zombie吧,如下:

class Zombie(object):
    '''This is a class called Zombie'''

    pass


现在,就可以利用上面的这个Zombie类,来创建一个僵尸对象,用变量z1来储存这个僵尸对象;并且再给这个僵尸对象添加一些属性,life属性代表它的生命值,combat代表它的战斗力,exp代表它的经验值。

>>> z1 = Zombie()
>>> z1.life = 100
>>> z1.combat = 7
>>> z1.exp = 0
>>> 
>>> z1.life
100
>>> z1.combat
7
>>> z1.exp
0

运行一下


自定义类的名称请首字母大写


类 - 构造器

虽然可以上述的方式来构建出很多小僵尸对象,但每次都需要构建完之后再对每个僵尸对象进行属性设定,这挺麻烦的,因此,最佳实践方法是在构造对象初始化的时候,就完成属性设置等相关工作;这种方法就叫构造器(constructor)。如下所示,__init__就是构造器,每次通过类创建对象时,把指定的属性值传到构造器中做相应处理即可;其中,self指的就是被创建的对象本身。

# coding=utf-8 

class Zombie(object):
    '''这是在声明Zombie类'''

    def __init__(self, life, combat, exp):
        '''这是构造器,用来初始化的'''
        self.life = life
        self.combat = combat
        self.exp = exp


传入构造器的形参life、combat、exp是构造器中的局部变量,只在构造器init方法中有效,因此需要将它们的值保存到该次用Zombie类创建的实例对象上,因此,将它们各自保存成该对象的相应属性即可。

>>> z1 = Zombie( 100, 7, 0 )
>>> print z1.life, z1.combat, z1.exp
100 7 0
>>> z2 = Zombie( 90, 3, 0 )
>>> print z2.life, z2.combat, z2.exp
90 3 0

运行一下


Zombie是;而根据Zombie类创建出的各个具体的僵尸对象,就是所谓的实例对象


类 - 方法

假设每个僵尸,进行一次学习(study)活动,经验值就会增加10。如果想把学习(study)这件事情作为僵尸对象的一种内置方法,就可以在自定义类时添加study这种方法。

# coding=utf-8 

class Zombie(object):
    '''这是在声明Zombie类'''

    def __init__(self, life, combat, exp):
        '''这是构造器,用来初始化的'''
        self.life = life
        self.combat = combat
        self.exp = exp

    def study(self):
        '''僵尸对象每进行1次学习,经验值增加10'''
        self.exp += 10

运行一下

类的特殊方法

作为类的构造器的__init__方法属于类的特殊方法之一;除此之外,python中类的特殊方法还有不少,比如__str__方法,该方法会返回一个字符串对象,当print该对象时,则会输出该字符串。

# coding=utf-8 

class Zombie(object):
    '''这是在声明Zombie类'''

    def __init__(self, life, combat, exp):
        '''这是构造器,用来初始化的'''
        self.life = life
        self.combat = combat
        self.exp = exp

    def __str__(self):
        '''设置print输出时的内容'''
        return "I am a Zombie( exp:%d )." % self.exp

    def study(self):
        '''僵尸对象每进行1次学习,经验值增加10'''
        self.exp += 10

运行一下

dir方法 - 查看对象的属性和方法

dir函数是python的内置函数,可用来查看对象的所有属性和方法;以上述Zombie类创建的对象为例,示例如下:

>>> z1 = Zombie( 100, 7, 0 )
>>> dir( z1 )
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'combat', 'exp', 'life', 'study']

运行一下

面向对象编程

类和对象是程序开发的利器之一;这类编程方式就是所谓的面向对象编程(Object-Oriented Programming,简称OOP或OO)。

针对面向对象编程,此处不打算着重介绍。但这里需要提到三点:封装、多态、继承。前两点不展开来说,请记住并细细揣摩如下:将跟类实例有关的所有数据、方法都隐藏封装在类中;如果想改变类实例的某个属性,请务必、一定、永远是通过类方法来操作实现,切忌直接赋值改变。

关于继承,这里只举一个简单的例子,紧接着上述的自定义类僵尸(Zombie)继续:在僵尸界,还有一种特殊的僵尸叫“麻辣僵尸”(HotZombie);麻辣僵尸在普通僵尸的基础上,有一个特殊的技能,就是传说中的“麻辣截体大法”,每个麻辣僵尸一生只能施展三次“麻辣截体大法”,当施展此法后,战斗力会翻10倍。但是生命值会减半,即变成当前生命值的一半。

很明显,HotZombie是基于Zombie类的;因此可以定义HotZombie类是就可以基于Zombie类来声明,这就是所谓的继承,HotZombie类继承了Zombie类所有的属性和方法。

# coding=utf-8 

class Zombie(object):
    '''这是在声明Zombie类'''

    def __init__(self, life, combat, exp):
        '''这是构造器,用来初始化的'''
        self.life = life
        self.combat = combat
        self.exp = exp

    def __str__(self):
        '''设置print输出时的内容'''
        return "I am a Zombie( exp:%d )." % self.exp

    def study(self):
        '''僵尸对象每进行1次学习,经验值增加10'''
        self.exp += 10

class HotZombie(Zombie):
    '''通过继承的方式来声明HotZombie类'''

    def __init__(self, life, combat, exp):
        '''这是构造器,用来初始化的'''
        Zombie.__init__( self, life, combat, exp )
        self.times = 0 # 记录使用过麻辣截体大法的次数

    def go_hot(self):
        '''施展麻辣截体大法'''
        # 判断使用此法的次数是否到达上限
        if self.times >= 3:
            print "fail" # 输出fail,代表施法失败
            return
        # 施展大法
        self.combat *= 10
        self.life *= 0.5
        self.times += 1
        print "success" # 输出success,代表施法成功    

运行一下


面向对象编程虽然强大,但是请不要过度使用此法,在适用的场景下,才能事半功倍;比如游戏开发领域就非常适合使用面向对象编程。不管是基于类和对象的方式,还是基于函数,编程的核心艺术都是把具体的问题抽象化、把复杂的问题拆分简单,在实现的过程中恪守低耦合、高分离的价值观。


类与对象

上一节 下一节