• python面向对象


    一.相关定义

    • 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
    • 类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
    • 数据成员:类变量或者实例变量, 用于处理类及其实例对象的相关的数据。
    • 方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
    • 局部变量:定义在方法中的变量,只作用于当前实例的类。
    • 实例变量:在类的声明中,属性是用变量来表示的。这种变量就称为实例变量,是在类声明的内部但是在类的其他成员方法之外声明的。
    • 继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。
    • 实例化:创建一个类的实例,类的具体对象。
    • 方法:类中定义的函数。
    • 对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。

    二.类

      相关知识:

      1.基本形式
        class 类名:
          """注释"""

          类体

      2.类规范:首字母大写
      3.类名加. 调用属性和方法
      4.方法

        - dir(类):查看属性和方法,返回一个列表
        - 类名.__dict__:查看属性可方法,返回键值对
        - __name__:查看类名

        - __doc__:文档信息,不能被继承,没有返回None

        - __base__:查看继承于哪个类

        - __module__:查看来自于哪个模块

        - __class__:查看哪个类来的类由type来

    三.实例

      1.实例=类名() --》生产实例
      2.__init__初始化,在产生实例的过程中会执行类的 __init__方法
      3.实例也可以通过 . 访问类的属性
      4.__dict__中 实例只绑定了属性,没有绑定方法,通过 . 访问类的方法执行
      5.self相当于实例本身,定义方式中的(self),全部相当于把实例传入进去
        实例.方法() <==>类.方法(实例)

     1 class Dog():  # 定义Dog类,首字母大写
     2     """
     3     定义Dog类
     4     """
     5 
     6     def __init__(self, name, type):
     7         self.name = name
     8         self.type = type
     9 
    10     def eat(self):
    11         print('%s在吃东西' % self.name)
    12 
    13     def run(self):
    14         print('%s在奔跑' % self.name)
    15 
    16 
    17 d = Dog('pp', '柯基')  # 实例化Dog
    18 print(d.name)
    19 print(d.type)
    20 d.eat()
    21 d.run()
    22 print(d.__dir__())  # 查看全部属性和内置方法
    23 print(d.__dict__)  # 查看属性,返回键值对,实例只绑定了属性,没有绑定方法,通过 . 访问类的方法执行
    24 print("---------------------------")
    25 print(Dog.__dict__)  # 查看类的属性和方法,返回键值对
    26 print(dir(Dog))  # 查看类的属性和方法,返回列表
    27 print(Dog.__name__)  # 查看类名
    28 print(Dog.__doc__)  # 查看文档
    29 print(Dog.__module__)  # 查看来自哪个模块
    30 print(Dog.__base__)  # 查看继承于哪个类
    31 print(Dog.__class__)  # 查看由哪个类来的,元类是type

    结果

     1 pp
     2 柯基
     3 pp在吃东西
     4 pp在奔跑
     5 ['name', 'type', '__module__', '__doc__', '__init__', 'eat', 'run', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
     6 {'name': 'pp', 'type': '柯基'}
     7 ---------------------------
     8 {'__module__': '__main__', '__doc__': '
        定义Dog类
        ', '__init__': <function Dog.__init__ at 0x0000023A817B5378>, 'eat': <function Dog.eat at 0x0000023A8285E158>, 'run': <function Dog.run at 0x0000023A8285E1E0>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>}
     9 ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'eat', 'run']
    10 Dog
    11 
    12     定义Dog类
    13     
    14 __main__
    15 <class 'object'>
    16 <class 'type'>

    四.类和实例的增删改查

      类

     1 class Dog():  # 定义Dog类,首字母大写
     2     x = 1
     3 
     4     def __init__(self, name, type):
     5         self.name = name
     6         self.type = type
     7 
     8     def eat(self):
     9         print('%s在吃东西' % self.name)
    10 
    11     def run(self):
    12         print('%s在跑' % self.name)
    13 
    14 
    15 d = Dog('xiaohong', '柯基')
    16 Dog.eat(d)  # 当调用类方法时需要手动传入实例对象,等价于d.eat()
    17 
    18 Dog.y = 2  # 增加属性
    19 Dog.x = 10  # 修改类属性
    20 
    21 def eat(self):
    22     print('修改后-->%s在吃' % self.name)
    23 
    24 
    25 Dog.eat = eat  # 修改类方法
    26 print(Dog.__dict__)
    27 d.eat()
    28 del Dog.y  # 删除类属性

      实例

     1 d.y = 20  # 增加属性,加入的是实例的__dict__字典,与类无关
     2 
     3 
     4 def sleep(self):  # 可以自定义实例的方法,但是注意要穿入参数,当调用类的方法时,会自动将实例传入self中
     5     print('%s正在睡觉' % self.name)
     6 
     7 
     8 d.sleep = sleep  # 增加实例方法
     9 del d.y  # 删除实例属性
    10 d.sleep(d)  # 注意此时需要传入self参数
    11 d.x=100  # 修改属性,不影响Dog的x的值
    12 print(d.__dict__)
    13 print(Dog.__dict__)
    1 xiaohong正在睡觉
    2 {'name': 'xiaohong', 'type': '柯基', 'sleep': <function sleep at 0x000002102FB8C1E0>, 'x': 100}
    3 {'__module__': '__main__', 'x': 1, '__init__': <function Dog.__init__ at 0x00000210319B5378>, 'eat': <function Dog.eat at 0x0000021032A4E158>, 'run': <function Dog.run at 0x0000021032A4E1E0>, '__dict__': <attribute '__dict__' of 'Dog' objects>, '__weakref__': <attribute '__weakref__' of 'Dog' objects>, '__doc__': None}

    五.类的相关装饰器和组合

    静态属性 @property 
    类方法 @classmethod
    静态方法 @staticmethod
     1 class Room:
     2     def __init__(self, name, length, width, height):
     3         self.name = name
     4         self.length = length
     5         self.width = width
     6         self.height = height
     7 
     8     @property  # 对于函数属性,可以不同加括号,相当于把函数属性转换成静态属性
     9     def area(self):
    10         res = self.length * self.width
    11         print('面积是%s' % res)
    12         return res
    13 
    14     @classmethod  # 类方法,不必要传入实例的属性,即不用传入self
    15     def tell_info(cls, place):  # 类和实例都可以调用,cls均不需要传入,系统默认将类传入cls
    16         print(cls)
    17         print('这是一个房子,位于%s' % place)
    18 
    19     @staticmethod  # 静态方法,与类和实例属性均无关,无法访问类和实例属性
    20     def happy(who, what):  # 类和实例均能调用
    21         print('%s在房子里干%s,很高兴' % (who, what))
    22 
    23 
    24 r = Room('客厅', 3, 4, 5)
    25 print(r.area)
    26 r.tell_info('浙江')
    27 Room.tell_info('浙江')
    28 Room.happy('ppp', 'sing_song')
    29 r.happy('ppp', 'sing_song')
    1 面积是12
    2 12
    3 <class '__main__.Room'>
    4 这是一个房子,位于浙江
    5 <class '__main__.Room'>
    6 这是一个房子,位于浙江
    7 ppp在房子里干sing_song,很高兴
    8 ppp在房子里干sing_song,很高兴

      组合

    大类包含小类
    把类的实例化放到一个新类里
    self.foot=Foot()
     1 class Fish:
     2     def __init__(self, type):
     3         self.type = type
     4 
     5     def swim(self):
     6         print('小鱼在快乐的游泳')
     7 
     8 
     9 class Turtle:
    10     pass
    11 
    12 
    13 class Pool:
    14     def __init__(self, f_num, t_num):
    15         self.f_num = f_num
    16         self.t_num = t_num
    17         self.fish = Fish('鲫鱼')
    18         self.turtle = Turtle()
    19 
    20     def swim(self):
    21         print('池塘里有%s只鱼,鱼的类型是%s,%s只乌龟' % (self.f_num, self.fish.type, self.t_num))
    22 
    23 
    24 p = Pool(10, 3)
    25 p.swim()
    26 # 池塘里有10只鱼,鱼的类型是鲫鱼,3只乌龟

    六.三大特性

      继承

        分类:单继承、多继承
        继承顺序:__mro__
      
        含义
          含义一:继承基类的方法,并且做出自己的改变或者扩展(代码重用)
          含义二:声明某个子类兼容于某基类,定义一个接口类,子类继承接口类,并且实现接口中定义的方法
        

     1 import abc
     2 
     3 
     4 class AllFile(metaclass=abc.ABCMeta):
     5 
     6     @abc.abstractmethod
     7     def write(self):
     8         pass
     9 
    10     def read(self):
    11         raise NotImplementedError("必须实现read方法")
    12 
    13 # 子类必须写write方法
    14 # 子类不写read方法,调用read报错,也需要自定义
    15 class MyFile(AllFile):
    16     def write(self):
    17         pass
    18     
    19     def read(self):
    20         pass
    21 
    22 
    23 file = MyFile()
    24 file.read()

      属性:1.同名子类不会覆盖父类的方法,是先从子类找,找不到去父类
         2.子类.__dict__没有父类的属性,但是可以调用
         3.在子类中调用父类的方法:super([子类,self]).父类方法()

      多态  

        1.由不同的类实例化得到的对象,调用同一个方法,执行的逻辑不同
        2.不同对象继承于同一父类,但是对父类同一方法有不同的响应行动

     1 print('asd'.__len__())
     2 print([1,2,5,6].__len__())
     3 print({'a:1,''b':1}.__len__())
     4 
     5 
     6 class Hho:
     7     def __init__(self,temp):
     8         self.temp=temp
     9     def state(self):
    10         if self.temp<=0:
    11             print('温度太低了,水结冰了')
    12         if 0<self.temp<100:
    13             print('温度合适,状态是水')
    14         if self.temp>=100:
    15             print('温度太高了,水汽化了')
    16 ice=Hho(-3)
    17 water=Hho(10)
    18 gas=Hho(130)
    19 ice.state()
    20 water.state()
    21 gas.state()

      “开闭”原则:

    • 对扩展开放(Open for extension):允许子类重写方法函数
    • 对修改封闭(Closed for modification):不重写,直接继承父类方法函数

      封装

        1.定义:

          在程序设计中,封装(Encapsulation)是对具体对象的一种抽象,即将某些部分隐藏起来,在程序外部看不到,其含义是其他程序无法调用。要了解封装,离不开“私有化”,就是将类或者是函数中的某些属性限制在某个区域之内,外部无法调用。


        2.实现方法:
          a. _ 单下划线开头:约定是内部属性,但是外部还是可以调用
          b. __ 双下划线开头:外部无法直接调用,但通过 _People__star 调用 --》(_类名__变量名)

        3.接口函数/访问函数:通过内部定义函数访问私有属性,外部可以通过函数访问

          @property 调用者不必关系内部怎么实现的,只需要调用属性即可

     1 class Foo:
     2     __x = 1
     3     __y = 2
     4 
     5     def __init__(self, m, n):
     6         self.__m = m
     7         self.__n = n
     8 
     9     @classmethod  # 封装的函数只能在内部调用,外部不能调用,外部调用需要写成 _类名__属性名
    10     def tem(cls):
    11         return cls.__x * cls.__y
    12 
    13     def temp(self):
    14         return self.__m * self.__n
    15 
    16     def __res(self):
    17         return self.__x * self.__y
    18 
    19     def res(self):
    20         return self.__x * self.__y
    21 
    22 
    23 f = Foo(5, 6)
    24 print(f._Foo__m)
    25 print(f.tem())
    26 print(f.temp())
    27 print(f.res())
    28 print(f._Foo__res())
    1 5
    2 2
    3 30
    4 2
    5 2

    七.反射

        1.内置函数
          hasattr(对象,属性):判断是否有属性
          getattr(对象,属性,[设置值]):获得属性,没有设置默认值,如果没有报错,设置了,没有返回设置的值
          setattr(对象,属性,value):设置属性,可以设置函数属性
          delattr(对象,属性):删除属性,不能删类的属性,只能删自己的

        2.补充:动态导入,通过字符串导入模块
          
          m=__import__('m1.t')
          得到的是顶级目录,m1,通过m1.t可以得到t模块


          通过importlib模块,m=importlib.import_module('m1.t')
          得到的是m1下的t模块


        3类的内置函数
          __getattr__:获取不存在的属性时执行
          __getattribute__:获取属性时执行,不管存不存在都执行,不存在时抛出异常AttributeError异常,然后__getattr__执行
          __setattr__:设置属性时执行,self.key=value,需要设置self.__dict__[k]=v ,如果设置self.k=v会无限递归
          __delattr__:删除属性时执行,删除对象属性不存在时也执行,需要设置self.__dict__.pop(item)-->删除的是字典key和value


          注意:继承基本类,重新定义函数,修改方法,注意修改时调用父类方法super(),否则会无限递归


        4.授权(类似于组合)
          file=open(file,mode,encoding)
          通过__getattr__(-->方法不存在时调用),然后返回getatter self.file.write()得到内置文件write方法
          可以重新定义 write() self.file.write() 重写write方法

     1 class Foo:
     2     x = 1
     3 
     4     def res(self):
     5         print('hello')
     6 
     7 
     8 f = Foo()
     9 print(hasattr(Foo, 'x'))
    10 setattr(Foo, 'y', 7)
    11 print(Foo.__dict__)
    12 print(getattr(Foo, 'y', '没有想要的值'))
    13 print(hasattr(f, 'x'))
    14 setattr(f, 'y', 7)
    15 print(f.__dict__)
    16 print(getattr(f, 'y', '没有想要的值'))
    17 delattr(f, 'y')
    18 
    19 # True
    20 # {'__module__': '__main__', 'x': 1, 'res': <function Foo.res at 0x0000016F23D85378>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None, 'y': 7}
    21 # 7
    22 # True
    23 # {'y': 7}
    24 # 7

    八.其他知识点

      1.一些内置函数
        isinstance(对象,类) : 对象是否是类实例化来的,类是父类也是True
        issubclass(类1,类2):类1是否是类2的子类,后面可以是元祖
      2.魔法方法
        __getitem__
        __setitem__
        __delitem__
          f1['name']=‘root’  --》 以字典形式操作时调用(容器类)
      3.str与repr
        (return 必须是字符串类型)
        __str__  --》 print()执行时调用,可以定制__str__,得到自己想要的结果
        __repr__ --》 在解释器中执行是调用
          print()先找__str__,找不到再找__repr__
      4.执行forrmat时执行__format__,返回值是必须是字符串
        可以重写定制format

      5.__slots__
        当一个类只有很少的属性但是有很多实例时,可以定义__slots__=['name','age']
        那么__solts__就代替了__dict__,且不能再增加额外的新的属性了
      6.__del__

        a.只有实例删除的时候会删除
        b.程序运行完成时内存释放会回收实例,执行__del__
      7.__call__

        后面加括号,触发执行
      8.__iter__
        只有有这个方法才能转换成迭代器对象,返回可迭代对象
      9.__next__
        设置next的返回值,定义错误raise StopIteration('终止了')
      10.上下文管理协议
        __enter__:with 运行时执行
        __exit__:with代码块执行完后执行

      

  • 相关阅读:
    px, pt, rpx, rem,
    tomcat报错LifecycleException的解决方案
    servlet系列
    tomcat startup.bat双击闪退解决方案。
    代码页
    editplus工具配置
    正则表达式常见字符集
    单片机TM4C123学习(六):看门狗
    stata学习笔记(七):回归分析和稳健性检验
    单片机TM4C123学习(五):UART的使用
  • 原文地址:https://www.cnblogs.com/pantong/p/10502852.html
Copyright © 2020-2023  润新知