zoukankan      html  css  js  c++  java
  • 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__],变量名))

  • 相关阅读:
    Win10 x64 + CUDA 10.0 + cuDNN v7.5 + TensorFlow GPU 1.13 安装指南
    工作十一年总结
    Anaconda3 指南
    Win Linux 双系统安装指南
    OBS 录制视频 自己留存
    React Starter Kit 中文文档
    .NET Framework 系统版本支持表
    Hyper-V和其他虚拟机共存 【转】
    Docker入门03——Container
    Docker入门02——Dockerfile详解
  • 原文地址:https://www.cnblogs.com/liusouthern/p/8289247.html
Copyright © 2011-2022 走看看