什么是面向对象呢?
面向对象
python本身就是一门面向对象的语言,面向对象的程序设计的核心是对象,首先要理解什么是对象及什么是类。
面向对象的优点:解决了程序的扩展性。
面向对象的缺点:可控性差。
什么时候能够用到面向对象呢 ?
非常明显的处理一类事物,这些事物都具有相似的属性和功能或者当有几个函数 需要反反复复传入相同的参数的时候,就可以考虑面向对象
python中一切皆为对象,类型的本质就是类,所以,不管你信不信,你已经使用了很长时间的类了
dict #类型dict就是类dict
<class 'dict'>
从上面的例子来看,字典就是一类数据结构,我一说字典你就知道是那个用{}表示,里面由k-v键值对的东西,它还具有一些增删改查的方法。但是我一说字典你能知道字典里具体存了哪些内容么?不能,所以对于一个类来说,它具有相同的特征属性和方法,没有确定的值。比如说‘’ 书 ‘’就是类,因为书有很多,但你不知道具体是数学书还是语文书。
而具体的{'name':'张三'}这个字典,它是一个字典,可以使用字典的所有方法,并且里面有了具体的值,它就是字典的一个对象。对象就是已经实实在在存在的某一个具体的个体。比如我有一本大学英语3的书,就是确定的对象。
在python中,用变量表示特征,用函数表示技能,因而具有相同特征和技能的一类事物就是‘类’,对象是则是这一类事物中具体的一个。
''' class 类名: '类的文档字符串' 类体 ''' #我们创建一个类 class Data: #Data 类名 属性 = 'a' #类属性
def __init__(self,*args): __init__初始化方法,self:在实例化时自动将对象/实例本身传给__init__的第一个参数 ,这里可以将self看作是一个可以存储很多属性的大字典
# self.name = args[0] # self.属性名 ,这里可以将self.name看作是字典的keys,传入的参数看作是values self.name==self.__dict__['name']
# self.hp = args[1]
# self.aggr = args[2]
# self.sex = args[3]
def attack(self,n): #这里的self一般情况都是需要传入的,参数n则根据需要
pass
k=Data(name,hp,aggr,sex) # 类名()表示创建一个对象k,也可以成为实例化。 对象=类名()
k.attcak(5) #调用方法 对象名.方法名(参数) 或者 Data.attack(k,5) # 类名.方法名(对象名,参数) print(k.__dict__) 查看所有属性
创建及调用类的模板
class 类名:
类的属性=‘ ’ #如果有需要显示显示类的属性 def __init__(self,参数1,参数2): self.对象的属性1 = 参数1 self.对象的属性2 = 参数2 def 方法名(self):
pass def 方法名2(self):
pass 对象名 = 类名(1,2) #对象就是实例,代表一个具体的东西 #类名() : 类名+括号就是实例化一个类,相当于调用了__init__方法 #括号里传参数,参数不需要传self,其他与init中的形参一一对应 #结果返回一个对象 对象名.对象的属性1 #查看对象的属性,直接用 对象名.属性名 即可 对象名.方法名() #调用类中的方法,直接用 对象名.方法名() 即可
练习:
利用类求长方形的面积和周长
class Ret: # def __init__(self,l,w): # self.l=l #计算时用对象名.属性计算 # self.w=w # def m(self,n): # return ('面积为:%s,%s'%((self.l*self.w),n)) # def z(self,n): # return ('周长为:%s,%s'%(((self.l+self.w)*2),n)) # # k=Ret(4,2) # print(k.z('cm')) # print(k.m('cm^2')) # print (k.__dict__['w']) # print(Ret.m(k,'cm^2'))
周长为:12,cm
面积为:8,cm^2
2
面积为:8,cm^2
类属性
类属性既可以被类名调用,同样也可以被对象调用,这一点和类中的方法(函数)是一样的。
# class Foo: # language = 'Chinese' #类属性变量为不可以数据类型 ,这里如果换成 language=['Chinese']等变量为可变数据类型,则在可以实现在对象中对其进行修改。 # def __init__(self,name,sex,job,): # self.name = name # self.sex = sex # self.job = job # def func(self): # pass # person1 = Foo('王二麻子', '男', 'IT PYTHON')
print(Foo.language) #类调用类属性 ,可以修改类属性
print(person1.language) #对象调用类属性 ,不可以修改类属性
Chinese
Chinese
如果我要通过类对类属性就行修改,且是在类中和对象中共享的: 尽量在类中进行修改
Foo.language='English'
print(Foo.language)
print(person1.language)
english
english
如果我要通过对象对类属性就行修改:
person1.language='English'
print(Foo.language)
print(person1.language)
Chinese
english #说明在对象中调用类属性,无法对其进行修改,只可以修改自身创建的。
这里用张图就可以生动的体现其中的关系:
类的组合
将另一个类的对象作为自己类的属性,就是类的组合。表达的是一种某某有某某的关系。
当类之间有显著不同,并且较小的类是较大的类所需要的组件时,用组合比较好
class Weapon: def prick(self, obj): # 这是该装备的主动技能,扎死对方 obj.hp -= 500 # 假设攻击力是500 class Person: # 定义一个人类 role = 'person' # 人的角色属性都是 def __init__(self, name): self.name = name # 每一个角色都有自己的昵称; self.weapon = Weapon() #类的组合 ,给角色绑定一个武器; 类的的属性=另外一个类的对象 police = Person('egon') police.weapon.prick() #这里的police.weapon就相当于Weapon()
#police组合了一个武器的对象,可以直接egg.weapon来使用组合类中的所有方法
#也可以表示为 police有武器有主动技
isinstance和issubclass
isinstance:用来判断对象是否在类中,返回值为布尔值。
若在类中则为True,若在类中则为False
issubclass:用来判断子类是父类中,返回值为布尔值。
若在类中则为True,若在类中则为False
# class A:pass # class B(A):pass # a = A() # print(isinstance(a,A)) #isinstance(对象,类) # print(issubclass(B,A)) #issubclass(子类,父类) # print(issubclass(A,B))
True
True
False
反射
用字符串类型的名字去操作变量。
反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr 获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子:
反射 对象 的属性和方法:
class A:
def __init__(self):
self.name='123'
def func(self):
print('456')
a=A()
#获取成员
ret1=getattr(a,'name') #==print(a.name)
print(ret1)
ret2=getattr(a,'func') #==a.func() 若果函数带参数,只需要在其后面加上(参数) ret2=getattr(a,'func')()(s)
ret2()
#检查成员 返回布尔值
print(hasattr(a,'name'))
ret=hasattr(a,func)
print(ret())
#设置成员
setattr(a,'name',789)
print(a.name)
#删除成员
delattr(a,'name')
print(a.name)
反射 类 的属性和方法:
class A:
k = 20
@classmethod
def func(cls):
print('abc')
#获取成员
ret=getattr(A,'k') #===print(A.k)
print(ret)
ret=getattr(A,'func')() #====print(A.func())
print()
#检查成员 返回布尔值
print(hasattr(A,'name'))
ret=hasattr(A,func)
print(ret())
#设置成员
setattr(A,'name',789)
print(A.name)
#删除成员
delattr(A,'name')
print(A.name)
在模块中同样可以使用反射
在内置模块中使用 # time # asctime # import time # print(getattr(time,'time')()) 反射在自己的模块中使用 # print(getattr(sys.modules[__name__],变量名))