以下代码块可以拼在一起,或者放在Jupyter中运行
- 类的建立
# -*- coding: gb2312 -*-
from types import MethodType
# 面向对象
# 建立一个类
class Hero(object):#所有类的父类都是object,当程序中没有需要继承的类可以就继承object,记得calss小写!
__slots__ = ('name','cont','weapon','__height','veh','vehicle') #向内部变量slots输入字符元组,用于限定类与对象的属性变量的定义。
count = 0 #类属性
def __init__(self,name,weapon,height): #__init__方法代表着该类的对象必要的属性,传入参数时解释器自己传self(该实例的变量名称),但其他参数必须调用时输入
self.name = name
self.weapon = weapon
self.__height = height #加了__后变量变成private变量
Hero.count += 1 #每次创建实例都会执行类属性的+1,这会改变所有的该类的对象(包括继承)
def hero_info(self): #将一个与该类有关的函数放在类中称为封装,这个函数称为类的方法
print('No.',self.count,' The ',self.name,' uses ',self.weapon,sep='')
# 之后会讲到@property
@property #对private的处理的读与写方法
def height(self):
return self.__height
@height.setter
def height(self,height): #对private的处理的写方法
if (100<height<300):
self.__height = height #private的调用要注意仍然保留__
else:
raise ValueError('Wrong Height')
Bruce_Wayen = Hero('Batman','fists',188)
# Bruce_Wayen.set_height(310) #实例方法的调用,可以通过函数访问私有变量,相比public变量这样可用来监测参数是否得当
Bruce_Wayen.hero_info()
- 继承与多态
#继承:被继承的类可以是Baseclass或者Superclass。继承者为Subclass
#多态:一个子类的类型既是父类也是子类。优点:开闭原则-‘对拓展开放,即给你新增Hero类’,‘对修改封闭,即不需要修改Hero类中的hero_info方法’
#ps.python是动态语言(运行时某些变量类型改变,比如不需要定类型),不一定要求继承,只需要方法中有hero_info就可以运行
class Story(Hero): #继承了Hero的所有方法与属性,当需要写一个Hero系列时(周边、电影、小说)就可以多用这样的subclass
def hero_info(self): #子类覆盖父类方法,这是多态发挥作用的前提!
print('No.',self.count," There is a ",self.name,' uses fear against the bad guys.',sep='') #子类的继承过程不会执行
def Hero_info(hero): #这就是多态的作用,下面的方法是Hero类型共有的,但子类与父类的方法不同。
hero.hero_info()
Bruce_Wayen_Story = Story('Batman','fists',188)
Hero_info(Bruce_Wayen_Story)
Hero_info(Bruce_Wayen)
- 检测类中信息
#检测类中的信息
print(isinstance(Bruce_Wayen_Story,Hero)) #可以判断是否是实例(包括继承的实例)
print(dir(Bruce_Wayen_Story)) #一个对象的方法与属性(包括继承),__XX__是object类与内置的
hasattr(Bruce_Wayen,'height') #判断是否有该属性,但是private仍然被隐藏
- 在类外绑定属性与方法
# 作为动态语言,python可以给实例或者给类加上属性与函数
def vehicle(self):
print(self.name,'moves by',self.veh)
Bruce_Wayen.veh = 'Batmotor' #为实例添加属性
Bruce_Wayen.vehicle = MethodType(vehicle,Bruce_Wayen) #为实例加方法,由于是动态语言,这里看起来像是加入了一个属性,所以再类里slots要添加进去
Bruce_Wayen.vehicle()
Story.vehicle = vehicle #为类添加方法
# dir(Story)
- 类的装饰器,帮助读写private属性
# 类中的装饰器@property,当我们需要限制类中的一个属性的值时(如Hero.height)要用到private变量,还需加入get与set函数,调用时有些麻烦,
# 可以用@property把调用方法转换:外界看起来是对属性的调取。@XX.setter让修改值的函数转换成:在外界看起来像是对属性的写
#不能通过再类外绑定的方式添加带有private的方法
# @property
# def height(self): #对private的处理的读方法
# return self.__height
# Hero.height = height
Bruce_Wayen.height = 187.9
Bruce_Wayen.height