• 面向对象


    类:面向对象

    • 面向对象三大特性:继承 多态 封装

    • 类:

      • 每个实例化的对象都封装了类中相同的属性和方法,类是一个相似功能的结合体,
      • 对象:类名加()就是一个对象,类中的属性就是变量
    • 实例化:当执行类名加括号时就是实例化的过程

      • 实例:就是将对象赋值给变量

    • 面向对象编程,函数式编程,统称面向过程式编程

    • 面向过程式编程好处:

      • 优点:出色的完成你之前布置的所有需求

      • 缺点:但凡更改或者增加一条需求,可能整个项目都会随之改变

    类的结构:

    • 类的调用:
    • class Student:  #构建学生类
          daily = '学习'            #变量在类中称为: 属性,静态属性 ,  静态字段 
          enamination = '考试'
      
          def work(self):           #函数在类中称为:方法,动态方法,   动态属性
              print('每天要上课')
      
          def homework(self):
              print('家庭作业')
      
      #类名的角度调用类中的属性:
      Student.cloth = "校服"                #增
      del Student.cloth                    #删
      Student.enamination = "不考试"        #改
      print(Student.enamination)           #查
      
      Student.work(44)  #工作中不使用       
      

    • self 方法传值:

    • #实例化对象时发生三件事:
      # 1.在内存中创建一个对象空间
      # 2.类名()自动执行__init__方法,并将这个对象空间(参数作为实参)传给self参数
      # 3.执行__init__方法里面的代码,给对象空间封装其属性
      
      #self 就是类中方法的第一个位置参数,
      #如果通过对象执行此方法,解释器就自动将此对象空间当做实参传给,self
      #约定俗称:类中的方法,第一个参数一般都设置成self
      
      class Student:                               #构建学生类,开启一个空间
          daily = '学习'                            #静态属性,类的属性
          enamination = '考试'
      
          def __init__(self,name,aex,hobby):       #双下方法  self接受的是obj实例化对象,封装属性
              self.name = name                     #name = '海洋'
              self.aex = aex
              self.hobby = hobby
      
          def work(self,color):                    #动态方法,类的方法
              self.color = color
              print(f"{self.name}每天要上课'")       #利用self对象空间,调用name属性
      
          def homework(self):
              print('家庭作业')
      
      # haiyang = Student('海洋',18,'台球')        #开辟一个haiyang空间,将参数传给self.name
      # junli   = Student('俊丽',18,'吃')
      # print(haiyang.__dict__)
      # print(junli.__dict__)
      
      #在任何地方都可以给对象封装属性
      haiyang = Student('海洋',18,'台球')         #haiyang对象 实例化,空间中存放着类指针
      haiyang.work("黑色")                        #可以在动态方法中添加属性
      print(haiyang.__dict__)
      
      #不可以在实例化里面修改静态属性
      # haiyang = Student('海洋',18,'台球')
      # haiyang.daily = "dada"   #不能修改,这样写没有修改类中的静态属性,而是在自己空间中添加
      # print(haiyang.daily)     #只能查看,不能修改类中的静态方法
      
      #obj = Student()           #实例化时开启一个空间,类名() 这是一个实例化过程,实例化一个对象
      # obj.age = '29'           #增
      # del obj.haha             #删
      # obj.sex = '女'            #改
      # print(obj.n)             #查看单个属性
      # print(obj.__dict__)      #查看全部属性,返回字典
      

    • 类添加属性和静态属性不可修改:

    • class A:
          address = "哒哒"
      
          def __init__(self,name):
              self.name = name
      
          def func(self):
              if self.name == 'aa':
                  self.skins = "海洋"
      
          def func1(self):
              print(self.__dict__)
              A.aaa = "俊丽"
      
      #在外面封装属性
      # obj = A("aa")
      # respons = input("输入1进行修改")
      # if respons == "1":
      #     obj.dudu = "海洋"
      #在内部封装属性
      # obj = A("aa")
      # obj.func()
      # print(obj.__dict__)
      
      obj = A('aa')
      A.func1(obj)
      print(A.__dict__)
      
      def obj.address
      #单项不可逆
      #对象与对象之间互相独立
      #对象如果查询一个属性:对象空间---->类空间---->父类空间
      #类查询一个属性:类空间----->父类空间
      

    • 依赖关系:

    • #类与类之间,将一个类的类名或者对象传给另一个类的方法中(当实参传)
      class Elephant:  #大象类
          def __init__(self,name):
              self.name = name
      
          def open(self,ref1):
              print(f"大象{self.name}默念三声:开门")
              ref1.open_door()
      
          def close(self,ref1):
              print(f"大象{self.name}默念三声:关门")
              ref1.close_door()
      
      class Refrigerator:  #冰箱类
          def __init__(self,name):
              self.name = name
      
          def open_door(self):
              print(f'{self.name}冰箱门被打开了')
      
          def close_door(self):
              print(f'{self.name}冰箱门被关上了')
      
      haiyang = Elephant('海洋')
      ref = Refrigerator('海尔')
      haiyang.open(ref)
      haiyang.close(ref)
      

    • 组合关系:

    • #将一个类的对象封装成另一个类的对象的属性
      #一个类的方法只能有此类的对象去调用‘
      #一个类的方法的第一个self只接受此类的对象
      
      class Boy:
          def __init__(self,name):   		      #双下方法,自动执行,封装属性
              self.name = name
      
          def meet(self,girl_friend = None):
              self.girl_friend = girl_friend
      
          def have_diner(self):    		      #self = wu对象空间
              if self.girl_friend:
                  print(f"{self.name}请{self.girl_friend.name}一起吃饭")
                  self.girl_friend.co(self)     #等同于flower.co,将self传给co self
              else:
                  print(f"一人吃饭")
      
      class Girl:
          def __init__(self,name,age):
              self.name = name
              self.age  = age
      
          def co(self,boy_friend):       #self = flower
              print(f"{boy_friend.name}和{self.name}一起溜达") 
      
      haiyang = Boy('海洋')
      flower = Girl('俊丽',18)
      
      haiyang.meet(flower)   		      #给meet传flower
      haiyang.have_diner()
      

    • 依赖和组合:

    • class Game():  # 英雄类
          def __init__(self, name, ad, hp):
              self.name = name
              self.ad = ad
              self.hp = hp
      
          def eauit_weapon(self, wea):  # wea == great_sword
              self.weapon = wea  # 组合:给盖伦这个对象封装了一个为wrapon属性
      
      
      class Weapon:  # 武器类
          def __init__(self, name, ad):
              self.name = name
              self.ad = ad
      
          def weapon_attack(self, p1, p2):
              p2.hp = p2.hp - self.ad
              print(f"{p1.name}利用{self.name}给了{p2.name}一下,{p2.name}还剩{p2.hp}滴血")
      
      
      gailun = Game('盖伦', 10, 100)  # 实例化人物
      jianhao = Game('赵信', 20, 90)
      
      great_sword = Weapon('大宝剑', 30)  # 实例化武器
      spear = Weapon('红缨枪', 40)
      
      gailun.eauit_weapon(great_sword)  # 依赖关系
      gailun.weapon.weapon_attack(gailun, jianhao)  # 给组合传参
      

    继承:

    • 继承,子类继承父类的属性和方法,实现代码的重用,减少代码的编写

    • 继承:

      • 优点:

        • 节省代码,增强耦合性,代码规范
      • 缺点:

        • 类的耦合性继承要少用

        • 可读性差,拍错难,容易出现意料之外的错误

    • 单继承:

      • 子类以及对象可以调用父类的属性或者方法,不能增删改

      • 子类中如果有此属性,不找父类

      • super方法:用于调用父类
      • class Animal:
            live = "生命"
        
            def __init__(self,name,age,sex):
                self.name = name
                self.age = age
                self.sex = sex
        
            def eat(self):
                # print(self)
                print("动物吃饭")
        
        class Person(Animal):
        
            def __init__(self,name,age,sex,hobby):
                #方法1    #调用Animal的双下方法
                #Animal.__init__(self,name,age,sex)          
                #方法2    #super方法,可以不写(),默认(Person, self)
                super(Person, self).__init__(name,age,sex)  
                self.hobby = hobby
        
            def eat(self):
                print("人类吃法")
                super().eat()            #调用父类方法
        
        p1 = Person("海洋",18,'男','台球')
        print(p1.__dict__)
        p1.eat()                        #调用子类eat方法
        

    • 多继承:

      • python2.2之前:都是经典类,

      • python2.2至python2.7之间存在两种类型:经典类,新式类

      • python3 只有新式类 默认继承 class A(object)

      • 经典类:基类不继承object,

        • 遵循深度优先原则
        • 深入的规则是从左至右,从左边一直找到最底层,在从最底层一层一层往回找
      • 新式类:基类必须继承object

        • 遵循mro算法,mro依赖于c3算法

    • 多继承示例和算法:

      • class God:  #神仙
            def __init__(self,name):
                self.name = name
        
            def fly(self):
                print("会飞")
        
            def climb(self):
                print("神仙也要爬树")
        
        class Monkey:  #猴子
            def __init__(self,sex):
                self.sex = sex
        
            def climb(self):
                print('爬树')
        
        class Monkey_Sun(God,Monkey):   #悟空
            pass
        
        sun = Monkey_Sun
        
        print(Monkey_Sun.mro())        #mor查看多继承继承顺序!
        
      • super 多继承

      • #super(S,self) 严格按照,self从属于类的mro的执行顺序,执行类的下一位
        #示例1:
        class A:
            def f1(self):
                print("in A")
        
        class Foo(A):
            def f1(self):
                super(Foo,self).f1()  #FOO下一个类Bar
                print("in Foo")
        
        class Bar(A):
            def f1(self):
                print("in Bar")
        
        class Info(Foo,Bar):
            def f1(self):
                super(Info,self).f1()   #Info属于第一个类,每次找下一个类,下个是Foo
                print("in info f1")
        
        obj = Info()
        obj.f1()
        
        #示例2:
        class A:
            def f1(self):
                print("in A")
            
        class Foo(A):
            def f1(self):
                super(Foo,self).f1()
                print("in Foo")
        
        class Bar(A):
            def f1(self):
                print("in Bar")
        
        class Info(Foo,Bar):
            def f1(self):
                super(Foo,self).f1()
                print("in info f1")
        
        obj = Info()
        obj.f1()
        

      • MRO算法,C3算法:

      • class O:
            pass
        class D(O):
            pass
        class E(O):
            pass
        class F(O):
            pass
        class B(D,E):
            pass
        class C(E,F):
            pass
        class A(B,C):
            pass
        
        #取第一个表头匹配表尾,不相同取出,如果相同,匹配下一个列表的表头
        #例子[C,E,F,O] = 表头[C] 表尾[E,F,O]
        #只能拿表头匹配
        """
        mro(A) = mro(A(B,C))  原式
               = [A] + merge(mro(B),mro(C),[B,C])
               
        mro(B) = mro(B(D,E))
               = [B] + merge(mro(D),mro(E),[D,E])   #多继承
               = [B] + merge([D,O],[E,O],[D,E])     #单继承,O都是单继承
               = [B,D] + merge([O],[E,O],[E])       #取出D之后,删除D 
               = [B,D,E,O]
               
        mro(C) = mro(C(E,F))
               = [C] + merge(mro(E),mro(F),[E,F])
               = [C] + merge([E,O]),[F,O],[E,F]) 
               = [C,E] + merge([O]),[F,O],[F])
               = [C,E,F,O] 
               
        mro(A) = mro(A(B,C))   原式
               = [A] + merge([B,D,E,O],[C,E,F,O],[B,C])
               = [A,B] + merge([D,E,O],[C,E,F,O],[C])
               = [A,B,D] + merge([E,O],[C,E,F,O],[C])
               = [A,B,D,C] + merge([E,O],[E,F,O]) 
               = [A,B,D,C,E] + merge([O],[F,O]) 
               = [A,B,D,C,E,F,O]
        
        """
        

    封装:

    • 将一些 数据属性和方法封装起来,还可以取出来,就是封装

    • 将你的数据放到列表里面也是封装,这是数据层面的

    • 常用的代码段放到函数里面,这是语句层面封装

    • 而类是一种更高级的封装,他可以将这两种封装在一起

    • 广义:

      • 把属性和方法装起来,外面不能直接调用了,要通过类的名字来调用
    • 狭义:

      • 把属性和方法藏起来,外面不能调用,只能在类的内部调用

    多态:

    • python:默认支持多态

      • 同一个对象,多种形态,A=1 A=“ad”
      • 一个类表现出多种形态,当你定义一个苹果支付类和微信支付类,他们同属于支付类,可以在支付类中定义双下方法属性

    • 鸭子类型:

      • python中 你看起来像鸭子,你就是鸭子
      • A,B两个类,没有任何关系,独立两个,但是里面的功能相似,所以python一般会将类似于A,B两个类里面的相似功能让其命名相同
      • A,B虽然无关系,但是很默契的制定了一个规范,让你使用更方便

    类的约束:

    • 类的约束是一个开发规范,约束他的所有子类必须实现和他同名的方法,不同名抛出错误
    • 作用:
      • 在重要的逻辑,与用户数据相关等核心部分,我们要进行约束,避免此类错误

    • 第一种约束(常用):主动抛异常

    • #在父类中定义个pay方法,主动抛出异常,如果子类中没有定义pay方法,会寻找父类
      #即会报错,python推荐的一种约束方式
      
      class Payment:             #主动报错
          def pay(self,money):   #约定俗称,定义一种规范,子类要定义pay方法
              raise Exception('子类必须定义此方法')
      
      class Alipay(Payment):
          def pay(self,money):
              print(f"利用支付宝支付了{money}")
      
      class Wechatpay(Payment):
          def fuqian(self,money):
              print(f"利用微信支付了{money}")
      
      #支付
      def pay(obj,money):
          obj.pay(money)
      
      obj1 = Alipay()       #调用支付宝支付
      pay(obj1,100)
      
      obj2 = Wechatpay()    #调用微信支付
      pay(obj2,200)
      
    • 第二种约束:实例化对象时报错,严谨

    • #利用抽象类的概念:基类如上设置,子类如果没有定义pay方法,在实例化对象时报错
      
      from abc import ABCMeta,abstractclassmethod
      
      class Payment(metaclass=ABCMeta):    #约束子类必须要有pay方法
          @abstractclassmethod
          def pay(self,money):
              pass
      
      class Alipay(Payment):
          def pay(self,money):
              print(f"利用支付宝支付了{money}")
      
      class Wechatpay(Payment):
          def fuqian(self,money):
              print(f"利用微信支付了{money}")
      
      #支付
      def pay(obj,money):
          obj.pay(money)
      
      obj1 = Alipay()
      obj2 = Wechatpay()    #调用微信
      
      pay(obj1,100)
      pay(obj2,200)
      

    反射:

    • 通过字符串形式,反射类中的属性和方法

    • 反射的四个函数:

    • hasattr(obj,"字符串")    #判断字符串是否存在类中
      getattr(obj,"字符串")    #进行反射调用字符串(属性或者方法)
      setattr(obj,"字符串")	  #添加属性
      delattr(obj,"字符串")    #删除属性
      

    • 实例角度反射:

    • class A:
          static_field = "静态属性"
      
          def __init__(self,name,age):
              self.name = name
              self.age = age
      
          def func(self):
              print("in A func")
      
      obj = A("海洋",18)
      
      if hasattr(obj,"static_field"):         #判断boj对象是否有static_field
          print(getattr(obj,"static_field"))   
      
      if hasattr(obj,"func"):                  #判断hasttr是否有函数
          getattr(obj,"func")()                #执行对象内的方法
      
      # print(getattr(obj,"name",None))  	     #没有属性,可以自定义设置返回值
      
      # setattr(obj,"hobby",'台球')       #* 添加一个属性
      # print(getattr(obj,"hobby"))
      #
      # delattr(obj,"hobby")             #*  删除一个属性
      # print(getattr(obj,"hobby"))
      

    • 类的角度反射:

    • class A:
          static_field = "静态属性"
      
          def __init__(self,name,age):
              self.name = name
              self.age = age
      
          def func(self):
              print(self)
              print(self.name)
              print("in A func")
      
      # print(hasattr(A,"static_field"))
      # print(getattr(A,"static_field"))
      obj = A("海洋",18)
      getattr(A,"func")(obj)
      

    • 脚本角度:

    • def func1():
          print("in func1")
      
      def func2():
          print("in func2")
      
      def func3():
          print("in func3")
      
      class B:
          static = "B类"
      
      import sys
      this_moudles = sys.modules[__name__]   #将__name__加入modules,获取当前脚本对象
      
      getattr(this_moudles,"func1")()      #调用函数
      
      cls = getattr(this_moudles,"B")      #获取到B,在进行实例化,调用
      obj = cls()
      print(obj.static)
      
      

    • 类的反射:

    • import sys
      
      class Auth:
          function_list = [("login","请登录"), ("register","请注册"),("exit","退出")]
      
          def login(self):
              print("登录函数")
      
          def register(self):
              print("注册函数")
      
          def exit(self):
              print("退出函数")
      
      while 1:
          obj = Auth()
          for num,option in enumerate(obj.function_list,1):
              print(num,option[1])
      
          func_name = int(input("请输入选择:").strip())
          if hasattr(obj,obj.function_list[func_name-1][0]):
              getattr(obj,obj.function_list[func_name-1][0])()
      

    单例模式:

    • 一个类只能实例化一个对象,无论你实例化多少次,内存中都只有一个对象,节省内存

    • 主要是实例化对象,执行类中的方法

    • #单例模式:(面试必考)
      #一个类只能实例化一个对象,无论你实例化多少次,内存中都只有一个对象,节省内存
      #这个类的对象不是个性化的,主要是实例化对象之后去执行类中的方法
      
      class A:
          __instance = None
      
          def __new__(cls, *args, **kwargs):
              if not cls.__instance:          #如果为反的话
                  obj1 = object.__new__(cls)  #调用object __new__方法封装类名
                  cls.__instance = obj1       #object1对象
                  return obj1
              else:
                  return cls.__instance
      
      obj = A()
      obj1 = A()
      print(obj,obj1)
      
      #传参示例:
      class Baby:
          __instance = None
      
          def __new__(cls, *args, **kwargs):
              if cls.__instance is None:
                  cls.__instance = object.__new__(cls)   #object=super,找父类__new__   object类中的new可以创建空间  Baby = cls
              return cls.__instance
      
          def __init__(self,cloth,pants):  #self  = b1
              self.cloth = cloth
              self.pants = pants
      
      b1 = Baby('黑衣服','黑裤子')
      b2 = Baby('白衣服','白裤子')
      print(b1.__dict__)
      print(b2.__dict__)
      

    类的成员:

    • 方法:

    • __ 将属性和方法变成私有

    • @classmethod : 调用类名

    • @staticmethod: 变成普通函数

    • @property : 将方法变成属性

    • 私有:

      • 私有静态属性,私有对象方法属性:
      • 类的外部都不可调用,只能在类中调用,适用于安全加密方式可以设置成私有(假私有)
    • #公有静态属性:
      class B:
          school_name = "海洋"
          __haha = "haha"
      
      class A(B):
          class_name = "python"
          __junli = "1"               #私有静态属性:外部不可访问
      
          def func(self):
              print(self.__junli)     #只能在类的内部可以访问
              print(self.__haha)
      
      obj = A()
      print(obj.func())
      
      #私有对象属性:
      class B:
          def __init__(self,weight):
              self.__weight = weight
      
      class A(B):
          def __init__(self,name,age,weight):
              super().__init__(weight)            #super要放在最上面
              self.name = name
              self.__age = age
      
          def func(self):
              print(self.__age)       #类的外部不能访问,只可以内部调用
              print(self.__weight)    #私有属性,父类中也不可调用
      
      obj = A("海洋",18,120)
      print(obj.func())
      
      #python中的所有私有成员:就是在私有成员前面加上_类名而已
      #不建议这样去访问
      class A:
          __junli = "1"
      print(A._A__junli)
      

    @classmethod:调用类名

    • #定义一个学生类,统计学生个数
      class Student:
          sum = 0
          def __init__(self,name):
              self.name = name
              self.count()
      
          @classmethod                #类方法:由类名直接调用的方法,他会自动将类名传给cls
          def count(cls):
              cls.sum = cls.sum + 1   #使用类名是可以修改静态方法中的sum
      
          @classmethod
          def get_num(cls):
              return cls.sum
      
      haiyang = Student("海洋")
      junli = Student("俊丽")
      print(Student.get_num())     #类名调用
      

    @staticmethod:变成普通函数

    • #静态方法:不依赖类,也不依赖于对象,他就是一个普通的函数
      #他就是一个普通的函数放置于类中结构更加清晰与合理
      class A:
      
          def func(self):
              print(111)
      
          @classmethod
          def a_func(cls):        #接受的是类名
              print(cls)
      
          @staticmethod
          def static_func(a):     #普通函数
              print(f"静态方法{a}")
      
      A.static_func(222)          #调用函数
      
      obj = A()			        #实例化调用也可以
      obj.static_func(222)
      
      

    @property :将方法变成属性

    • #测试人体体脂
      #我们要让bmi方法,伪装成属性,虽然在代码级别没有什么提升,但是看起来更合理
      class Bmi:
          def __init__(self,name,weight,height):
              self.name = name
              self.weight = weight
              self.height = height
      
          @property   #将方法转为属性
          def bmi(self):
              return self.weight / self.height**2
      
      tb = Bmi("海洋",120,1.80)
      print(tb.bmi)               #调用属性
      
      
      #@property 方法变成属性,修改和删除不常用
      class Foo:
          def __init__(self,name):
              self.name = name
      
          @property
          def aaa(self):              #设置属性是名称要唯一,setter和deleter不能return
              print('get时候执行我')
      
          @aaa.setter
          def aaa(self,v):
              print(f"修改的时候执行我{v}")
      
          @aaa.deleter
          def aaa(self):
              print("删除时候执行我")
      obj = Foo("海洋")
      obj.aaa = "俊丽"        #调用被@aaa.setter装饰的函数,并且将"俊丽"传给v
      del obj.aaa            #删除
      
      print(obj.aaa)         #原属性aaa没有被修改
      

    isinstance:判断对象与类的关系

    • class A:
          pass
      class B(A):
          pass
      class C(B):
          pass
      
      obj = B()
      print(isinstance(obj,B)) #前面是对象,判断OBJ是否是是由B类(B的派生类)实例化的对象
      print(isinstance(obj,A)) #
      print(isinstance(obj,C)) #
      

    issubclass:

    • class A:     		    #父类,也叫基类
          pass
      class B(A):
          pass
      class C(B):
          pass
      
      print(issubclass(C,B))  #判断C是否是B的子类,子类也叫派生类
      print(issubclass(C,A))
      

    Iterable:判断类可迭代和元类

    • from  collections import Iterable   #判断是否可迭代
      from  collections import Iterator   #判断迭代器
      
      s1 = "sadaada"          #class str(Iterable):
      # l1 = [1,2,3]
      # print(type(s1))       #判断对象从属于哪个类,一切皆对象
      # print(type(l1))
      
      print(isinstance(s1,Iterable))       #判断是否是可迭代对象,从继承角度
      
      #type 元类  python中一切皆对象,一个类也是一个对象
      #那么一个类肯定是由类实例化出来的
      #python中你创建的所有类,以及大部分str list等等,这些类都是从type元类实例化得来的
      
      # python中继承object都是新式类:
      # object也是有type元类实例化得来的
      #而type类还是object子类,这种关系比较神奇无法使用python代码表述
      

    types:

    • #函数与方法区别
      #函数:全都是显性传参
      #方法:存在隐性传参     #java里面就是有方法,c++中都是函数
      
      from  types import  FunctionType  #判断函数
      from types import MethodType      #判断方法
      
      def func():
          pass
      
      class A:
          def func(self):
              pass
          @staticmethod
          def f(self):
              pass
      
      print(isinstance(func,FunctionType))      #判断是否是函数
      print(isinstance(func,MethodType))
      
      print(isinstance(A.func,FunctionType))    #类名调用func 是一个函数
      print(isinstance(A.func,MethodType))
      
      obj = A()
      print(isinstance(obj.func,FunctionType))
      print(isinstance(obj.func,MethodType))    #通过对象调用是方法
      
      obj = A()
      print(isinstance(obj.f,FunctionType))     #通过对象调用静态方法是函数
      print(isinstance(obj.f,MethodType))
      

    双下方法:

    • 双下方法触发条件:

      • __new__:  在实例化时候触发,触发优先级比__init__高,单例模式使用
        __len__:  len(obj)  len对象时候触发
        __str__:  str(obj)或者格式化输入时候触发
        __call__: 实例化对象后触发,call优先级比__init__方法低
        

    • __new__方法:

    • #开辟一个空间
      class A:
          def __init__(self):
              print("in init")
      
          def __new__(cls, *args, **kwargs):  #cls = A类名
              print("in new")
              object1 = object.__new__(cls)   #2.利用object类的new产生一个空间
              return object1                 #3.将这个对象空间返回给A()
      
      obj = A()                              #1.先触发__new__并且将类名自动传给cls
      

    • __len__方法:

    • #一个对象值所以可以使用len函数,是这个对象从属于类中有__len__方法
      class A:
          def __init__(self,name,age,hobby):
              self.name = name
              self.age = age
              self.hobby = hobby
      
          def __len__(self):
              print("执行了__len__方法")
              return len(self.__dict__)
      
      obj = A("海洋",18,"台球")
      ret = len(obj)             #触发A类中的__len__方法,ret返回10
      print(ret)
      
    • __str__方法:

    • class Student:
          def __init__(self,name,age,sex):
              self.name = name
              self.age = age
              self.sex = sex
      
          def __str__(self):
              return  f"{self.name}{self.age}{self.sex}"  #str优先级高
      
          # def __repr__(self):   #跟str双下方法一样
          #     return  f"{self.name}{self.age}{self.sex}"
      
      obj = Student("海洋",18,"男")
      obj1 = Student("俊丽",18,"女")
      # # print(str(obj))  #会触发
      # print(obj)    #打印一个实例就会触发__str__
      # print(obj1)
      print(f"此对象为{obj}") #格式化输出也会触发
      
    • __call__方法:

    • # 对象call ,类加()触发
      class A:
          def __init__(self):
              self.a = 1
              print(111)
      
          def __call__(self, *args, **kwargs):
              print(222)
      
      obj = A()   #实例化触发
      obj()
      
    • __enter__和__exit__方法:

    • #对一个对象类似于进行with语句上下文管理,必须要在类当中定义__enter__和__exit__
      class A:
          def __init__(self,text):
              self.text = text
      
          def __enter__(self):
              self.text = self.text + "您来了"  #1
              return self
      
          def __exit__(self, exc_type, exc_val, exc_tb):
              self.text = self.text + "这就走了"  #
      
      with A("大爷") as f1:  #2
          print(f1.text)
      print(f1.text)  #4
      

    • #__eq__    对象比较是触发
      #__del__   析构方法,手动垃圾挥手
      #__item__  对一个对象,执行字典的操作,执行item
      #__iter__  将一个对象设置成一个可迭代对象,for循环取值或者list
      

    异常处理:

    • 一旦程序出现异常,异常处理会及时捕捉你的错误,不至于使你的程序崩溃

    • 异常处理不能经常使用:耗费性能,有些错误是需要分流使用的,代码的可读性变差

    • 关键的节点时候使用

    • 单分支:

    • try:
          l1 = [1,2,3,4,5]
          print(l1[6])
      
      except IndexError as e:   #当索引报错后,后面的就不会再走了
          print("索引错误")
      
      print(111)
      

    • 多分支和分流:

    • try:
          l1 = [1,2,3,4,5]
          print(l1[6])
      
          dic = {1:2,'a':'b'}
          print(dic[3])
      
          num = input("请输入序号:")
          int(num)
      
      except IndexError as e:   #当索引报错后,后面的就不会再走了
          print("索引错误")
      except KeyError as e:   
          print('没有此键')
      except ValueError as e:
          print("转化错误")
      print(111)
      
      #程序分流
      dic = {
          1:666,
          2:333,
          3:555
      }
      
      while 1:
          try:
              num = input("请输入序号:")
              int(num)
              print(dic[int(num)])
      
          except KeyError as e:  					 
              print(f'选项超出范围,请重新输入{e}')    #e是将错误打印出来
          except ValueError as e:
              print(f"请输入数字{e}")
      

    • 万能异常:

    • # 万能异常
      # 什么时候使用万能异常,什么时候使用多分支?
      # 如果你只是想把整个异常全部处理掉,让程序继续执行,就用万能异常
      # 如果出现了异常,你是想根据不同的异常执行不同的逻辑流程,你要采取多分支
      
      dic = {
          1:666,
          2:333,
          3:555
      }
      
      try:
          num = input("请输入序号:")
          int(num)
          print(dic[int(num)])
      
      except Exception as e:   #代表所有错误,全部捕获
          print(e)
      print(111)
      
      

    • 万能异常加分流:

    • dic = {
          1:666,
          2:333,
          3:555
      }
      while 1:
          try:
              num = input("请输入序号:")
              int(num)
              print(dic[int(num)])
      
          except KeyError as e:
              print('选项超出范围,请重新输入')
          except ValueError as e:
              print("请输入数字")
          except Exception:       	#以上异常没有pass掉
              pass
      
      

    • 异常处理其他成员:无异常时候执行

    • dic = {
          1:666,
          2:333,
          3:555
      }
      try:
          num = input("请输入序号:")
          int(num)
          print(dic[int(num)])
      
      except KeyError as  e:
          print("选项超出范围,重新输入")
      except Exception:
          pass
      else:         					 #以上无异常执行else语句,否则不执行else语句
          print(666)
      
      

    • finally:在出现错误前执行此语句

    • #使用场景,文件读写,数据库连接
      try:
          int("a")
      finally:                #finally:  在出错误前执行此语句
          print(777)
      
      def func():             #函数结束前执行finally
          try:
              a = 1
              b = 2
              return  a + b
          finally:
              print(666)
      print(func())
      

    • raise/assert:主动抛出异常

    • raise Exception("主动抛出异常")
      
      assert          #断言:可以添加条件加判断
      assert  1 == 2
      print(11)
      

    • 自定义异常(了解)

    • class Connection(BaseException):
          def __init__(self,msg):
              self.msg=msg
      
      raise Connection("触发了连接异常")
      
  • 相关阅读:
    c# WinForm 定时执行某个后台操作 如把B文件夹下的文件Copy到A文件夹下
    c# 创建指定大小的空字符填充的文本文件 在指定位置读写相关内容
    c# DirectShow 通过IAMVideoProcAmp的Set方法 来设置视频图像的Brightness 调整亮度
    [转]灰度图像的腐蚀算法和细化算法(C#代码)
    利用fleximage实现图片上传
    利用acts_as_ferret实现全文检索
    纯CSS无hacks的跨游览器多列布局
    IE私有CSS样式属性一览
    利用thinking sphinx实现全文检索
    搭建rails运行环境
  • 原文地址:https://www.cnblogs.com/haiyang11/p/11157792.html
Copyright © 2020-2023  润新知