python的面向对象

什么是面向对象呢?

  面向对象

  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__],变量名))

 

posted @ 2018-01-15 18:08  排骨南  阅读(281)  评论(0编辑  收藏  举报