文章目录

  • 类属性
  • 类方法
  • 静态方法
  • 继承和super()
  • 给子类添加方法
  • 重写父类方法
  • 命名规则
  • 模块、类和引入
  • 标准库中的类
  • 其他实例作为属性
  • 写一个简单的英雄联盟

类属性

类属性创建有点类似于在类中创建一个全局变量,这个变量类跟实例都可以调用它

# 定义一个模板
class Dog():# 定义一个类属性number_of_dogs = 0# 构造方法 - 添加实例属性,做其他初始化工作def __init__(self,name,height,power):self.name = nameself.height = height# 设置血量为默认属性,值为10self.blood = 10self.power = powerprint '{}出生了!汪汪~'.format(self.name)# 添加一个方法barkdef bark(self):print '我是{},身高{},攻击力{},血量{}'.format(self.name,self.height,self.power,self.blood)# 再添加一个attack()方法来执行攻击这个行为def attack(self,dog):dog.reduce_blood(self.power)def reduce_blood(self,reduce_value):if reduce_value > self.blood:self.blood = 0else:self.blood = self.blood-reduce_value
# 创建多个实例
d1 = Dog('大黄',0.7,3)
d2 = Dog('二黑',0.5,4)# 通过类访问类属性
print Dog.number_of_dogs# 通过实例访问类属性
print d1.number_of_dogs
print d2.number_of_dogs

唯一不同的是,在修改属性的值的时候,变量跟实例的区别是很大的

#省略部分代码
# 创建多个实例
d1 = Dog('大黄',0.7,3)
d2 = Dog('二黑',0.5,4)# 类修改类属性
Dog.number_of_dogs = 8# 通过类访问类属性
print Dog.number_of_dogs# 实例修改类属性
d1.number_of_dogs = 10# 通过实例访问类属性
print d1.number_of_dogs
print d2.number_of_dogs

来看一下运行结果:

总结:

  1. 整个类只有一份,所有实例都共享这一份。
  2. 可以通过类名或者实例名访问类属性,访问的都是同一个。
  3. 修改类属性需要通过类名。
  4. 因为通过实例名就会创建一个同名的实例变量。
  5. 当实例属性与类属性同名时,通过实例访问则实例属性优先。

类方法

类方法就是定义一个属于类的方法,定义格式与实例方法相似,不过要在方法上一行加 @classmethod装饰器来声明:

class Dog():dogs = []# 构造类方法,返回狗的数量@classmethoddef number_of_dogs(cls):return len(cls.dogs)# 构造类方法,返回最高大的狗@classmethoddef biggest(cls):max_height = 0for i in cls.dogs:if i.height > max_height:max_height = i.heightreturn max_height# 构造方法 - 添加实例属性,做其他初始化工作def __init__(self,name,height,power):self.name = nameself.height = heightself.blood = 10self.power = powerprint '{}出生了!汪汪~'.format(self.name)Dog.dogs.append(self)# 实例化类
d1 = Dog('大黄',70,10)
d2 = Dog('二黑',50,15)# 调用类方法输出当前狗的数量
print '当前狗的数量为:{}只'.format(Dog.number_of_dogs())
# 调用类方法返回最高大的狗
print '当前狗狗最高身高为:{}公分'.format(Dog.biggest())

练习:

构造一个类方法,要求返回height大于50的狗的数量class Dog():dogs = []big_dogs = []# 构造一个类方法,要求返回height大于50的狗的数量@classmethoddef num_of_big_dog(cls):for i in Dog.dogs:if i.height > 50:Dog.big_dogs.append(i)print '身高大于50公分的狗有{}只'.format(len(Dog.big_dogs))# 构造方法 - 添加实例属性,做其他初始化工作def __init__(self,name,height,power):self.name = nameself.height = heightself.blood = 10self.power = powerprint '{}出生了!汪汪~'.format(self.name)Dog.dogs.append(self)# 实例化多个对象
d1 = Dog('大黄',70,10)
d2 = Dog('二黑',50,15)
d3 = Dog('三傻',45,20)
d4 = Dog('四喜',62,13)
d5 = Dog('五白',30,20)
# 调用类方法输出height大于50的狗的数量
Dog.num_of_big_dog()

静态方法

之前我们学习了两个方法:实例方法类方法,实例方法的第一个参数是实例,只能调用实例属性,调用类属性则会创建一个与类属性同名的实例属性;类方法的第一个参数是类,只能调用类属性。

如果有一个方法它属于这个类,它既不需要使用实例属性,也不需要使用类属性,那么这个方法就是静态方法

class Dog:# 定义静态方法@staticmethoddef info():print "Dog is human's best friend~"# 实例化一个对象
d1 = Dog()# 调用静态方法
Dog.info()
d1.info()

继承和super()

现在我们手上有3只狗,分别是警犬、牧羊犬、宠物犬,它们有各自的特性,但也有共同的属性,这时候就要用到类的继承了。

具体代码可以这样实现:

# 定义构造方法
class Dog(object):def __init__(self,name,power,height):self.name = nameself.height = heightself.power = powerself.blood = 10# 构造bark方法def bark(self):print '我是{},汪汪~'.format(self.name)# 定义一个SheepDog类,它是Dog的子类,继承Dog的构造方法
class SheepDog(Dog):# 定义构造方法,这里添加了一个特性num_of_sheepsdef __init__(self,name,power,height,num_of_sheeps):# 用super()初始化构造父类,这里的super()函数与python3中有所不同!super(SheepDog,self).__init__(name,power,height)# 设置方法属性self.num_of_sheeps = num_of_sheeps# 实例化一个对象
sd = SheepDog('牧羊犬',10,70,5)
# 调用父类方法
sd.bark()

现在我们做一个练习,把其余的两只狗也定义出来,只定义属性,先不定义它们的方法:

# 定义构造方法
class Dog(object):def __init__(self,name,power,height):self.name = nameself.height = heightself.power = powerself.blood = 10# 构造bark方法def bark(self):print '我是{},汪汪~'.format(self.name)# 定义牧羊犬
class SheepDog(Dog):# 定义构造方法,这里添加了一个特性num_of_sheepsdef __init__(self,name,power,height,num_of_sheeps):# 用super()初始化构造父类,这里的super()函数与python3中有所不同!super(SheepDog,self).__init__(name,power,height)# 设置方法属性self.num_of_sheeps = num_of_sheeps# 定义警犬
class PoliceDog(Dog):def __init__(self,name,power,height,ability):super(PoliceDog,self).__init__(name,power,height)self.ability = ability# 定义宠物犬
class PetDog(Dog):def __init__(self,name,power,height,price):super(PetDog, self).__init__(name,power,height)self.price = price# 牧羊犬
sd = SheepDog('牧羊犬',10,70,5)
print sd.blood
sd.bark()# 警犬
pd = PoliceDog('警犬',20,65,7)
print pd.blood
pd.bark()# 宠物犬
petd = PetDog('宠物犬',1,3,10)
print petd.blood
petd.bark()

给子类添加方法

我峨嵋你继承父类以后,可以使用它的构造方法以及它的类属性,但子类也会有自己的方法,就像上文中的三只狗,它们有一个自己的方法,这时候我们就需要给子类定义方法了。


添加方法的方式其实也很简单,就是在子类中定义一个新的方法罢了:

# 定义构造方法
class Dog(object):def __init__(self,name,power,height):self.name = nameself.height = heightself.power = powerself.blood = 10# 构造bark方法def bark(self):print '我是{},汪汪~'.format(self.name)# 定义一个SheepDog类,它是Dog的子类,继承Dog的构造方法
class SheepDog(Dog):# 定义构造方法,这里添加了一个特性num_of_sheepsdef __init__(self,name,power,height,num_of_sheeps):# 用super()初始化构造父类,这里的super()函数与python3中有所不同!super(SheepDog,self).__init__(name,power,height)# 设置方法属性self.num_of_sheeps = num_of_sheepsdef protect(self):print '我开始保护羊群了,汪汪!'# 定义警犬
class PoliceDog(Dog):def __init__(self,name,power,height,ability):super(PoliceDog,self).__init__(name,power,height)self.ability = abilitydef detect(self):print '我开始侦擦了,汪汪!'# 定义宠物犬
class PetDog(Dog):def __init__(self,name,power,height,price):super(PetDog, self).__init__(name,power,height)self.price = pricedef sing(self):print '我开始唱歌了,汪汪!'# 牧羊犬
sd = SheepDog('牧羊犬',10,70,5)
sd.bark()
# 调用牧羊犬子方法
sd.protect()# 警犬
pd = PoliceDog('警犬',20,65,7)
pd.bark()
# 调用警犬子方法
pd.detect()# 宠物犬
petd = PetDog('宠物犬',1,3,10)
petd.bark()
# 调用宠物犬子方法
petd.sing()

重写父类方法

重写的格式就是在子类中定义一个与父类方法同名的子方法即可:

# 定义构造方法
class Dog(object):def __init__(self,name,power,height):self.name = nameself.height = heightself.power = powerself.blood = 10# 构造bark方法def bark(self):print '我是{},汪汪~'.format(self.name)# 定义一个SheepDog类,它是Dog的子类,继承Dog的构造方法
class SheepDog(Dog):# 定义构造方法,这里添加了一个特性num_of_sheepsdef __init__(self,name,power,height,num_of_sheeps):# 用super()初始化构造父类,这里的super()函数与python3中有所不同!super(SheepDog,self).__init__(name,power,height)# 设置方法属性self.num_of_sheeps = num_of_sheepsdef protect(self):print '我开始保护羊群了,汪汪!'# 定义警犬
class PoliceDog(Dog):def __init__(self,name,power,height,ability):super(PoliceDog,self).__init__(name,power,height)self.ability = abilitydef detect(self):print '我开始侦擦了,汪汪!'def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)# 定义宠物犬
class PetDog(Dog):def __init__(self,name,power,height,price):super(PetDog, self).__init__(name,power,height)self.price = pricedef sing(self):print '我开始唱歌了,汪汪!'# 警犬
pd = PoliceDog('警犬',20,65,7)
# 重写父类方法
pd.bark()
# 调用警犬子方法
pd.detect()

如果你想既重写了父类方法,又要调用原父类方法的话,我们可以用super()来实现这个功能

# 定义构造方法
class Dog(object):def __init__(self,name,power,height):self.name = nameself.height = heightself.power = powerself.blood = 10# 构造bark方法def bark(self):print '我是{},汪汪~'.format(self.name)# 定义一个SheepDog类,它是Dog的子类,继承Dog的构造方法
class SheepDog(Dog):# 定义构造方法,这里添加了一个特性num_of_sheepsdef __init__(self,name,power,height,num_of_sheeps):# 用super()初始化构造父类,这里的super()函数与python3中有所不同!super(SheepDog,self).__init__(name,power,height)# 设置方法属性self.num_of_sheeps = num_of_sheepsdef protect(self):print '我开始保护羊群了,汪汪!'# 定义警犬
class PoliceDog(Dog):def __init__(self,name,power,height,ability):super(PoliceDog,self).__init__(name,power,height)self.ability = abilitydef detect(self):print '我开始侦擦了,汪汪!'# 调用父类方法super(PoliceDog,self).bark()def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)# 定义宠物犬
class PetDog(Dog):def __init__(self,name,power,height,price):super(PetDog, self).__init__(name,power,height)self.price = pricedef sing(self):print '我开始唱歌了,汪汪!'# 警犬
pd = PoliceDog('警犬',20,65,7)
# 重写父类方法
pd.bark()

练习:

把剩下的两只狗的bark方法也进行重写# 定义构造方法
class Dog(object):def __init__(self,name,power,height):self.name = nameself.height = heightself.power = powerself.blood = 10# 构造bark方法def bark(self):print '我是{},汪汪~'.format(self.name)# 定义牧羊犬
class SheepDog(Dog):# 定义构造方法,这里添加了一个特性num_of_sheepsdef __init__(self,name,power,height,num_of_sheeps):# 用super()初始化构造父类,这里的super()函数与python3中有所不同!super(SheepDog,self).__init__(name,power,height)# 设置方法属性self.num_of_sheeps = num_of_sheepsdef protect(self):print '我开始保护羊群了,汪汪!'def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)super(SheepDog, self).bark()# 定义警犬
class PoliceDog(Dog):def __init__(self,name,power,height,ability):super(PoliceDog,self).__init__(name,power,height)self.ability = abilitydef detect(self):print '我开始侦擦了,汪汪!'def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)# 调用父类方法super(PoliceDog,self).bark()# 定义宠物犬
class PetDog(Dog):def __init__(self,name,power,height,price):super(PetDog, self).__init__(name,power,height)self.price = pricedef sing(self):print '我开始唱歌了,汪汪!'def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)super(PetDog, self).bark()# 牧羊犬
sd = SheepDog('牧羊犬',10,70,5)
# 重写父类方法
sd.bark()# 警犬
pd = PoliceDog('警犬',20,65,7)
# 重写父类方法
pd.bark()# 宠物犬
petd = PetDog('宠物犬',1,3,10)
# 重写父类方法
petd.bark()

命名规则

类名:驼峰,如SheepDog、PoliceDog
方法名、变量名、参数、文件名:全小写,多个单词下划线连接如:get_pwd,start_attack如果是文件名,可以变成getpwd,为了引用起来方便
私有属性:在属性前加_,例如_weight,不过依然可以访问,只是一种命名规范
Python解释器御用:方法前加__,例如:__init__

模块、类和引入

现在我们创建一个新的文件game.py,引用我们上文写好的dog.py,像这样就可以了

import dogpet_dog = dog.PetDog('小可爱',1,30,998)
pet_dog.bark()
print pet_dog.price

标准库中的类

我们结合标准库中的类来进行一个继承,在python中有一个Turtle类,是一个绘图海龟,现在我们来写一个属于自己的小海龟

这里物品们定义一个自己的类Myturtle,并且定义一个自己的方法big_circle:

import turtleclass MyTurtle(turtle.Turtle):def big_circle(self):self.color('red')self.circle(100)s = turtle.Screen()
t = MyTurtle()
t.big_circle()
s.mainloop()

运行结果:

后续我会在另一篇文章中更新一下这个部分,本文中就先不做过多介绍了

其他实例作为属性

假设现在我们要给每条出厂的宠物狗配置一个狗窝,我们可以通过__init__方法添加参数来实现,也可以构造一个DogHost方法,把他实例化来充当宠物狗的属性:

# 定义构造方法
class Dog(object):def __init__(self,name,power,height):self.name = nameself.height = heightself.power = powerself.blood = 10self._weight = 30# 构造bark方法def bark(self):print '我是{},汪汪~'.format(self.name)# 定义一个SheepDog类,它是Dog的子类,继承Dog的构造方法
class SheepDog(Dog):# 定义构造方法,这里添加了一个特性num_of_sheepsdef __init__(self,name,power,height,num_of_sheeps):# 用super()初始化构造父类,这里的super()函数与python3中有所不同!super(SheepDog,self).__init__(name,power,height)# 设置方法属性self.num_of_sheeps = num_of_sheepsdef protect(self):print '我开始保护羊群了,汪汪!'def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)super(SheepDog, self).bark()# 定义警犬
class PoliceDog(Dog):def __init__(self,name,power,height,ability):super(PoliceDog,self).__init__(name,power,height)self.ability = abilitydef detect(self):print '我开始侦擦了,汪汪!'def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)# 调用父类方法super(PoliceDog,self).bark()# 定义宠物犬
class PetDog(Dog):def __init__(self,name,power,height,price,house):super(PetDog, self).__init__(name,power,height)self.price = priceself.house = housedef sing(self):print '我开始唱歌了,汪汪!'def bark(self):print '我是{},这是我自己的方法,我重写了父类方法~'.format(self.name)super(PetDog, self).bark()# 定义狗窝
class DogHost:def __init__(self,num):self.num = numprint '{}号狗窝已创建'.format(self.num)

定义好了之后,我们去另一个game.py脚本中引用它:

import doghouse = dog.DogHost('9527')
pet_dog = dog.PetDog('小可爱',1,20,998,house)

运行结果:

写一个简单的英雄联盟

  1. 参考王者荣耀或者你喜欢的其他游戏,创建相应的类和实例。
  2. 要求至少有3个类。
  3. 要求必须有继承关系。
  4. 要求必须有实例属性和类属性。
  5. 要求必须有实例方法和类方法。

我的答案:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2020/10/27 15:51
# @Author  : Shadow
# @Site    :
# @File    : LOL.py
# @Software: PyCharm# 定义一个Hero类作为父类
class Hero(object):# 定义类属性num_of_hero = []# 定义构造方法,并把生成的英雄追加到num_of_hero这个类属性中def __init__(self,name,blood,mana,power):self.name = nameself.blood = bloodself.mana = manaself.power =powerprint '英雄【{}】已生成!'.format(self.name)self.num_of_hero.append(self)# 定义attack方法执行攻击行为def attack(self,hero):hero.blood = hero.blood - self.powerif hero.blood > 0:print '{}剩余血量为:{}'.format(hero.name,hero.blood)else:hero.blood = 0print '{}已被{}击杀!'.format(hero.name,self.name)# 定义info方法来输出英雄属性def info(self):print '名称:{}\n血量:{}\n法力值:{}\n攻击力:{}'.format(self.name,self.blood,self.mana,self.power)# 定义Tank类作为Hero类的子类
class Tank(Hero):# 定义构造方法def __init__(self,name,blood,mana,power,armor):# 继承父类属性super(Tank, self).__init__(name,blood,mana,power)# 定义实例属性self.armor = armorself.blood = blood+armor*0.5# 定义info方法来输出英雄属性,这里继承了父类的info方法并进行了重写def info(self):super(Tank, self).info()print '护甲:{}'.format(self.armor)# 定义Assassin类作为Hero类的子类
class Assassin(Hero):def __init__(self,name,blood,mana,power,critical_strike):super(Assassin, self).__init__(name,blood,mana,power)self.power = power+critical_strike*0.5self.critical_strike = critical_strikedef info(self):super(Assassin, self).info()print '暴击率:{}%'.format(self.critical_strike)# 定义Master类作为Hero类的子类
class Master(Hero):def __init__(self,name,blood,mana,power,magic):super(Master, self).__init__(name,blood,mana,power)self.magic = magicself.power = power*0.5+magicdef info(self):super(Master, self).info()print '法强:{}'.format(self.magic)# 实例化三个类
SaiEn = Tank('塞恩',1500,100,300,200)Jie = Assassin('劫',1200,100,220,90)Ali = Master('阿狸',1000,500,100,300)if __name__ == '__main__':# 调用类属性并输出当前英雄总数print '当已生成{}个英雄!'.format(len(Hero.num_of_hero))# 调用attack方法进行10次攻击,直至英雄死亡为止for i in range(10):Jie.attack(SaiEn)if SaiEn.blood <= 0:breakelse:continue# 调用子类info方法,输出当前信息SaiEn.info()

详解python中的面向对象(下)相关推荐

  1. 详解Python中的封装

    文章目录 详解Python中的封装 基础入门 -> setter.getter 进阶使用 -> __ 私有属性 _ 强化加强 -> property 详解Python中的封装 面向对 ...

  2. python open 打开是什么类型的文件-详解Python中open()函数指定文件打开方式的用法...

    文件打开方式 当我们用open()函数去打开文件的时候,有好几种打开的模式. 'r'->只读 'w'->只写,文件已存在则清空,不存在则创建. 'a'->追加,写到文件末尾 'b'- ...

  3. [转载] python中for语句用法_详解Python中for循环的使用_python

    参考链接: 在Python中将else条件语句与for循环一起使用 这篇文章主要介绍了Python中for循环的使用,来自于IBM官方网站技术文档,需要的朋友可以参考下 for 循环 本系列前面 &q ...

  4. python操作符op_详解python中的 is 操作符

    大家可以与Java中的 == 操作符相互印证一下,加深一下对引用和对象的理解.原问题: Python为什么直接运行和在命令行运行同样语句但结果却不同,他们的缓存机制不同吗? 其实,高票答案已经说得很详 ...

  5. python正则匹配空格+数字+空格_详解Python中正则匹配TAB及空格的小技巧

    详解Python中正则匹配TAB及空格的小技巧 发布时间:2020-10-15 08:38:48 来源:脚本之家 阅读:94 作者:杰瑞26 在正则中,使用.*可以匹配所有字符,其中.代表除\n外的任 ...

  6. python的装饰器迭代器与生成器_详解python中的生成器、迭代器、闭包、装饰器

    迭代是访问集合元素的一种方式.迭代器是一个可以记住遍历的位置的对象.迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束.迭代器只能往前不会后退. 1|1可迭代对象 以直接作用于 for ...

  7. python中heapq的库是什么_详解Python中heapq模块的用法

    详解Python中heapq模块的用法 来源:中文源码网    浏览: 次    日期:2018年9月2日 [下载文档:  详解Python中heapq模块的用法.txt ] (友情提示:右键点上行t ...

  8. python 协程可以嵌套协程吗_Python | 详解Python中的协程,为什么说它的底层是生成器?...

    今天是Python专题的第26篇文章,我们来聊聊Python当中的协程. 我们曾经在golang关于goroutine的文章当中简单介绍过协程的概念,我们再来简单review一下.协程又称为是微线程, ...

  9. python中break怎么用_详解Python中break语句的用法

    详解Python中break语句的用法 在Python中的break语句终止当前循环,继续执行下一个语句,就像C语言中的break一样. break最常见的用途是当一些外部条件被触发,需要从一个循环中 ...

最新文章

  1. vue.config.js配置代理不生效_npm install的代理问题
  2. Linux学习总结(7)——阿里云centeros服务器上安装 jdk,tomcat,mysql
  3. sql server创建数据库与相关查询操作
  4. 程序员离职代码交接_程序员离职大半个月,被老板命令回单位讲代码,员工:一次1万...
  5. 使用JAVASCRIPT进行全屏显示页面,就像触摸屏显示效果
  6. C语言!鸡兔同笼的程序
  7. 霍尔编码器原理及测速--PID—arduino
  8. Vue2.0 Vue组件库
  9. Python精灵模块:走来走去的小猫咪
  10. 浅层砂过滤器(浅层介质过滤器)介绍及现场案例反馈图(多图)
  11. 如何下载网页的FLASH视频
  12. 滤波器原理及其作用计算机网络,滤波器的原理与作用
  13. 几种常见嵌入式实时操作系统简介
  14. 搜狐新闻数据400w+
  15. 【历史上的今天】1 月 23 日:现代集成电路雏形;JDK 1.0 发布;数学大师诞生
  16. 今天有空,不如来找找“双鸭山大学”的由来吧~
  17. 【DSP】离散系统的因果性判断
  18. 远程桌面连接服务器时,键盘不能正常打字
  19. Computed property “XXX“ was assigned to but it has no setter
  20. 使用convert命令将pdf转成图片时遇到的一个问题

热门文章

  1. JS函数封装三个例子
  2. 权益质押(Staking):这是关于什么的?
  3. 关于 第三方接口支付的时候 采用post提交的方式,有两种 一种是通过 curl来进行,一种是通过js当页面加载完后跳转...
  4. 哔哩哔哩淘宝小程序盲盒抽奖实践
  5. pytroch:model.train()、model.eval()的使用
  6. Ubuntu 添加右键菜单项
  7. Sequel pro 简单使用
  8. Demo系列一之 Form表单下载Excel文件
  9. obs源码 windows编译
  10. css样式超出部分省略号