zoukankan      html  css  js  c++  java
  • 我的python学习之路-oop面向对象

    本节内容:

      一、类的基础

        1.1 类的定义

        1.2 .类的实例化

        1.3 类的结构

        1.4 类的命名

             二、封装

        2.1 封装-对象的操作

        2.2 封装-类的相关

        2.3  注意点-对象和类之间的不同

        2.4 访问类中的私有成员

        2.5 删除类对象中公有成员属性方法

      三、继承

        3.1 单继承

        3.2 多继承

      四、多态

        4.1基本概念及使用例子

       五、魔术方法

        5.1 __init__构造方法

        5.2 __new__ 魔术方法

        5.3 单态(例)模式

        5.4 __del__ 析构方法

        5.5__call__魔术方法

        5.6__str__魔术方法

        5.7__repr__魔术方法

        5.8__bool__ 魔术方法

        5.9 __add__ 魔术方法  (与之相关的 __radd__ 反向加法)

        5.10 __len__ 魔术方法

      六、魔术属性

        6.1包含成员及例子

     

    一、类的基础

    1、类的定义

    # 推荐使用
    class MyCar():
        pass
        
    class MyCar:
        pass
        
    class MyCar(object):
        pass

    2、类的实例化

    class MyCar():
        pass
    # 类的实例化 / 实例化对象
    obj = MyCar()
    print(obj)

    3、类的基本结构

    1. 成员属性
    2. 成员方法                
    class MyCar():
        # 成员属性
        color = "粉色系"
        # 成员方法
        def didi():
            print("会滴滴的叫")

    4、类的命名

    类的命名 => 推荐使用大驼峰命名法;
    mycar => MyCar
    mycat => MyCat
    chengfabiao => ChengFaBiao

    二、封装

    封装等级:

    1. 公有:在类的内部和外部都可以访问到
    2. 私有:  在类的内部可以使用,再类外无法调用

    成员:

    1. 成员属性
    2. 成员方法

    调用:

    1. 对象.成员属性
    2. 对象.成员方法

    绑定方法:

    1. 绑定到对象:对象.类中方法()时,系统会自动把该对象当成参数传递到方法中;
    2. 绑定到类  :对象.类中方法()或者类.方法()时,系统会自动把该类当成参数传递到方法中

     1.封装-对象的相关操作

    定义一个类

    class Car():
        # 公有成员属性
        color = "黄色"
        
        # 私有成员属性
        __price = "200多万"
        
        # 公有方法
        def run(self):
            # 类内调用公有成员  self <=> obj 
            print(self.color,"内部")
            # 类内调用私有成员
            print(self.__price)
            print("小车每秒140米的速度前进")
        
        # 私有方法
        def __drive():
            print("小车可以无人驾驶")

    (1)实例化的对象访问公有成员属性和方法

    # 实例化对象
    obj = Car()
    #
    访问属性 print(obj.color,"<外部>") # print(obj.__price) #error # 访问方法 obj.run() # obj.__drive() #error

    (2)实例化的对象动态添加公有成员属性和方法

           obj优先调用自己的,在调用类的,都没有报错

      1) 、  添加成员属性
    obj.engine = "16缸发动机"
    obj.color = "绿色" # 优先调用对象自己的颜色
    print(obj.engine)
    print(obj.color)
    obj.run()
    # __dict__ 查看对象或者类中的内部成员,返回字典
    print(obj.__dict__)
    print(Car.__dict__)
      2)、添加成员方法

        注意点: 对象.类外方法()时,系统不会自动把该对象当成参数传递到该方法中

        (1)、添加无参方法
    def dahuangfeng():
        print("变形~ 我叫大黄蜂")
    obj.dahuangfeng = dahuangfeng
    obj.dahuangfeng()
    print(obj.__dict__)
        (2)、添加有参方法

    基本版:

    def qingtianzhu(name):
        print("变形~ 我叫{}".format(name))
    
    obj.qingtianzhu = qingtianzhu
    obj.qingtianzhu("一柱擎天")

    升级版 (手动传递obj),由于要用对象中的其他的属性,所以要传递obj

    def qingtianzhu(obj,name):
        print( "变形~ 我叫{}".format(name) , "颜色为{}".format(obj.color)  )
    
    obj.qingtianzhu = qingtianzhu
    obj.qingtianzhu(obj,"擎天柱")

    究极版 (自动传递obj)

      MethodType => 创建绑定方法(绑定到对象) 让系统自动帮助我们传递obj对象

    import types
    """types.MethodType(函数,对象)"""
    func = types.MethodType(qingtianzhu,obj)
    print(func)
    obj.qingtianzhu = func
    obj.qingtianzhu("擎天柱")
        (3) 添加lambda 表达式
    obj.hongzhizhu = lambda : print("变形~ 我是反派角色红蜘蛛")
    obj.hongzhizhu()

     2、封装 - 类相关操作

    定义一个类

    class Taxi():
        # 公有成员属性
        platenum = "粤B 666888"
        # 私有成员属性
        __earn = "12000"
        
        # 公有方法
        def lake():
            print("出租车经常拉客人~")
        
        # 私有方法
        def __ranquan():
            print("部分司机绕圈圈~")

    (1)定义的类访问公有成员属性和方法

    obj = Taxi()
    """类中的无参方法只能类来调用;"""
    # obj.lake()
    # 成员属性
    print(Taxi.platenum)
    # Taxi.__earn error
    # 成员方法
    Taxi.lake()

    (2)定义的类动态添加公有成员属性和方法

    (1)、动态添加成员属性
    Taxi.luntai = "米其林"
    print(Taxi.luntai)
    print(obj.luntai) #米其林 对用可以调用 
    print(Taxi.__dict__)
    print(obj.__dict__) #{} 看看出对象和类是两个内存空间
    (2)、动态添加成员方法
    (1) 无参方法
    def fangxiangpan():
        print("我是制造方向盘的方法")
    
    Taxi.fangxiangpan = fangxiangpan
    Taxi.fangxiangpan()
    (2) 有参方法
    def engin(name):
        print("我是制造{}的方法".format(name))
    Taxi.engin = engin
    Taxi.engin("EA888")
    (3) lambda表达式
    Taxi.zuoyi = lambda : print("我是制造加热座椅的方法")
    Taxi.zuoyi()

    3、注意点: 对象和类之间的不同

    (1)对象去调用类中方法时,系统都会默认传递该对象参数;

    (2)对象可以默认调用类中的公有成员,反过来,类不能调用对象中的相关成员.

    (3)一个类可以创建多个对象,而对象和对象之间是彼此独立的;

    4、访问类中私有成员

    定义一个类

     1 class Plane():
     2 
     3     # 公有成员属性
     4     captain = "李雅琪"
     5     
     6     # 私有成员属性
     7     __airsister = "10个空姐"
     8     
     9     # 公有成员方法
    10     def fly(self):
    11         print("飞机飞到平流层,可以飞机的机身的抖动")
    12     
    13     # 私有成员方法
    14     def __price(self):
    15         print("飞机的价格保密")
    16         
    17     # 公有无参成员方法
    18     def fly2():
    19         print("飞机在降落时,落地的一瞬间会向上弹起,请记好安全带")
    20     
    21     # 私有无参成员方法
    22     def __info():
    23         print("关于飞机中的机长和空姐的信息保密")
    24         
    25     # 利用公有方法调取私有成员[对象操作]
    26     def pub_info1(self):
    27         print(self.__airsister)
    28         self.__price()
    29         
    30     # 利用公有方法调取私有成员[类操作]
    31     def pub_info2():
    32         print(Plane.__airsister)
    33         Plane.__info()
    View Code

    (1 ).方法一 私有化的实现方式:改名策略 (不推荐,破坏了封装性)

    # 实例化对象
    obj = Plane()
    print(Plane.__dict__)
    # 类去访问私有成员属性
    print(Plane._Plane__airsister)
    # 类去访问私有成员方法
    Plane._Plane__info()
    
    # 对象去访问私有成员属性
    obj._Plane__airsister
    # 对象去访问私有成员方法
    obj._Plane__price()

     2.方法二 利用一个公有方法,间接调用私有成员 (推荐)

    obj.pub_info1()
    Plane.pub_info2()

    注意点:如果无参只能类来调取,如果有参,对象和类都能调取

    # obj.pub_info2() #error
    Plane.pub_info1(obj)

    5、删除类对象中公有成员属性方法

    1.删除成员时,一定要注意,该成员归属于谁,如果对象中没有该成员,只有使用的权利,没有删除和修改的权利

    2.对象获取成员时,先看自己空间有没有,如果有就调取,否则上类中成员寻找,如果类中也没有,直接报错

    定义一个类:

     1 class Plane():
     2 
     3     # 公有成员属性
     4     captain = "李雅琪"
     5     
     6     # 私有成员属性
     7     __airsister = "10个空姐"
     8     
     9     # 公有成员方法
    10     def fly(self):
    11         print("飞机飞到平流层,可以飞机的机身的抖动")
    12     
    13     # 私有成员方法
    14     def __price(self):
    15         print("飞机的价格保密")
    16         
    17     # 公有无参成员方法
    18     def fly2():
    19         print("飞机在降落时,落地的一瞬间会向上弹起,请记好安全带")
    20     
    21     # 私有无参成员方法
    22     def __info():
    23         print("关于飞机中的机长和空姐的信息保密")
    24         
    25     # 利用公有方法调取私有成员[对象操作]
    26     def pub_info1(self):
    27         print(self.__airsister)
    28         self.__price()
    29         
    30     # 利用公有方法调取私有成员[类操作]
    31     def pub_info2():
    32         print(Plane.__airsister)
    33         Plane.__info()
    View Code

    1、删除对象中的属性

    obj.captain = "家营和" # 不能删除类中的,只能自己添加
    print(obj.__dict__)
    del obj.captain
    print(obj.captain,"<111>") 

    2、删除对象中的方法

    obj.pub_info1 = lambda : print("我是pub_info方法")
    del obj.pub_info1

    3、 删除类中的属性

    del Plane.captain
    #print(Plane.captain) error
    # print(obj.captain,"<2222>") error

    4、删除类中的方法

    del Plane.pub_info1
    # Plane.pub_info1(obj) error
    # obj.pub_info1() error

     三 、继承

    继承:一个类除了自身所拥有的属性方法之外,还获取了另外一个类的成员属性和方法

    被继承的就是父类(基类,超类)
    继承的就是子类(衍生类)

    python中所有类的父类是object

    1、单继承

    class Human():
        
        property1 = "远古人类不穿衣服"
        
        def fire(self):
            print("远古人类钻木去火")
        
        def drinkblood(self):
            print("远古人类茹毛饮血")
        
        def __mao(self):
            print("远古人类一身毛,不能碰")
            
            
    class Man(Human):
        pass

    1、子类继承了父类之后,子类可以使用父类的公有成员

    obj = Man()
    print(obj.property1)

    2、子类继承了父类之后,子类不能使用父类的私有成员

    class Woman(Human):
        def pub_func(self):
            self.__mao()
    obj = Woman()
    # obj.pub_func() error

    3、 子类继承了父类之后,子类可以重写父类的公有成员

    class Children(Human):
    
        def drinkblood(self):
            print("刚出生的小孩只能喝奶奶")
    
    obj = Children()
    obj.drinkblood()

    4、总结

    在继承的环境当中,对象的调取顺序:
    先查看自己对象中是否含有该成员 => 自己的类是否含有 => 该类的父类是否含有 => 报错

    2、多继承

    1.基本用法

    class Father():
        f_pty = "风流倜傥,玉树临风,一枝梨花压海棠"
        def f_hobby(self):
            print("打麻将,吃喝嫖赌,开跑车约妹子")
        
    class Mother():
        m_pty = "倾国倾城,貌美如花,一直红杏出墙来"
        def m_hobby(self):
            print("打麻将,蹦野迪,勾引小鲜肉")
    
    class Daughter(Father,Mother):
        pass
        
    obj = Daughter()
    print(obj.f_pty)
    obj.m_hobby()

    2.深度使用

    (1)super本身是一个类 super()是一个对象 用于调用父类的绑定方法
    (2)super() 只应用在绑定方法中,默认自动传递self对象 (前提:super所在作用域存在self)
    (3)super用途: 解决复杂的多继承调用顺序

     1 class Father():
     2     pty = "风流倜傥,玉树临风,一枝梨花压海棠"
     3     def hobby(self):
     4         print(self)
     5         print("打麻将,吃喝嫖赌,开跑车约妹子")
     6     
     7 class Mother():
     8     pty = "倾国倾城,貌美如花,一直红杏出墙来"
     9     def hobby(self):
    10         print("打麻将,蹦野迪,勾引小鲜肉")
    11 
    12 class Son(Father,Mother):
    13     pty = "可爱,有趣,爱学习,爱劳动,三道杠"
    14     
    15     def hobby(self):
    16         print("喜欢打游戏,lol,wow.dnf.ddo,cs,cf")
    17     
    18     # 1.使用类调用类中成员
    19     def skill1(self):
    20         # 调用mother中的成员
    21         print(Mother.pty)
    22         Mother.hobby(self)
    23         
    24         # 调用father中的成员
    25         print(Father.pty)
    26         # Father.hobby()
    27     
    28     # 2.使用对象调用类中成员
    29     """obj调用成员时,会按照 obj成员 -> 子类成员 -> 父类成员"""
    30     def skill2(self):
    31         print(self.pty)
    32         # obj.hobby() error
    33         self.hobby()
    34         
    35     # 3.使用super调用类中成员
    36     """1.super只调用父类的绑定方法 2.会自动把该对象当成参数进行传递"""
    37     def skill3(self):
    38         print(super)
    39         print(super()) 
    40         print(super().pty)
    41         super().hobby()
    42 
    43 obj = Son()
    44 print("<=======1========>")
    45 obj.skill1()
    46 print("<=======2========>")
    47 obj.skill2()
    48 print("<=======3========>")
    49 obj.skill3()
    View Code

    3、菱形继承

    class Human():
        pty = 4
        def feelT(self):
            print("天热了,脱毛1")
            print(self.pty)
            print("天冷了,穿貂2")
            
    class Man(Human):
        pty = 3
        def feelT(self):
            print("天热了,光膀子3")
            super().feelT()
            print("天冷了,穿貂4")
    
    class Woman(Human):
        pty = 2
        def feelT(self):
            print("天热了,脱衣服5")
            super().feelT()
            print("天冷了,多喝热水6")
    
    class Children(Man,Woman):
        pty = 1
        def feelT(self):
            print("天热了,光屁股7")
            super().feelT()
            print("天冷了,喝奶8")
    
    obj = Children()
    obj.feelT()
    # 7 3 5 1 2 6 4 8
    print(obj.pty)#1

    mro列表:方法解析顺序列表

    类.mro() => 方法解析顺序列表
    super调用的顺序要依赖mro列表所呈现的顺序,依次调用;
    作用: super用途: 解决复杂的多继承调用顺序(菱形继承)

    super要点:
    1.super只调用父类成员
    2.super调用父类成员采用广度优先原则(依照类.mro列表顺序调用)
    3.super调用父类方法时,会自动传递该对象参数

    4、相关函数

    (1)、.issubclass 判断子类与父类 (类与类之间的关系)

      issubclass在判断子父关系时候,只要在一条继承链上,有继承关系即可
      1).issubclass(子类,父类)
      2).issubclass(子类,(父类1,父类2,父类3 ... ))

     (2)、isinstance 判断对象的类型 (对象与类之间关系)

      1).isinstance(对象,类)

      2)isinstance(对象,(类1,类2,类3)

    四 、多态

    1、基本概念及使用例子

    多态 : 不同的子类对象,调用相同的父类方法,产生不同的执行结果

    特征 : 继承 重写 针对于对象

     1 class Soldier():
     2     # 攻击方法
     3     def attack(self):
     4         pass
     5     
     6     # 撤退方法
     7     def back(self):
     8         pass
     9     
    10     
    11 class Army(Soldier):
    12     def attack(self):
    13         print("手撕鬼子,包子手雷")
    14     
    15     def back(self):
    16         print("飞檐走壁,日行八百,夜行一千")
    17         
    18 class Navy(Soldier):
    19     def attack(self):
    20         print("扔鱼叉,勤撒网,往回拉鬼子")
    21         
    22     def back(self):
    23         print("潜水,划水,水遁,下水憋气30个小时")
    24     
    25 class AirForce(Soldier):
    26     def attack(self):
    27         print("射导弹,扔手雷")
    28         
    29     def back(self):
    30         print("契机跳伞,落地成盒")
    31     
    32 # 创建陆军士兵
    33 objArmy = Army()
    34 # 创建海军士兵
    35 objNavy = Navy()
    36 # 创建空军士兵
    37 objAirForce = AirForce()
    38 
    39 # 各就位准备
    40 lst = [objArmy,objNavy,objAirForce]
    41 
    42 strvar = """
    43 各就位准备,将军请下令:
    44 1.全体出击
    45 2.全体撤退
    46 3.陆军上,其他兵种撤退
    47 """
    48 
    49 num = input(strvar)
    50 for i in lst:
    51     # print(i)
    52     if num == "1":
    53         i.attack()
    54     elif num == "2":
    55         i.back()
    56     elif num == "3":
    57         # 判断对象类型是陆军
    58         if isinstance(i,Army):
    59             i.attack()
    60         else:
    61             i.back()
    62     else:
    63         print("风大太,我听不见~")
    64         break
    65         
    View Code

    五、魔术方法

    定义:系统自动调用的方法,按照触发机制调用

    1、 __init__构造方法

    触发时机:实例化对象,初始化的时候触发
    功能:为对象添加成员
    参数:参数不固定,至少一个self参数
    返回值:无

    (1) 基本使用-无参数的

    class MyClass():
        def __init__(self):
            self.name = "~李琦~"
            print("构造方法被触发了... ")
    
    # 实例化对象
    obj = MyClass()
    print(obj.name)

    (2)带有参数的构造方法

    class MyClass():
        def __init__(self,name):
            self.name = name
    
    # 在实例化对象时,给与构造方法实参
    obj1 = MyClass("朱培峰")
    obj2 = MyClass("黄常见")
    print(obj1.name)
    print(obj2.name)

    (3)类可以是一个,对象可以是多个,不同的对象之间数据彼此隔离

     1 class Children():
     2 
     3     # 构造方法
     4     def __init__(self,name,skin):
     5         # 为对象添加成员
     6         self.name = name
     7         self.skin = skin
     8     # 公有成员方法(绑定到对象)
     9     def cry(self):
    10         print("小孩一生产出来,就会哇哇哇的哭")
    11 
    12     # 公有成员方法(绑定到对象)
    13     def eat(self):
    14         print("小孩一生产出来,就会吃奶奶")
    15 
    16     # 私有成员方法(绑定到对象)
    17     def __laugh(self):
    18         print("小孩一生产出来,就仰天长笑,老子终于出来了.")
    19         
    20     # 面向对象的写法(让对象操作一切) 推荐
    21     def info1(self):
    22         print("小孩的姓名是{},小孩的肤色是{}".format(self.name , self.skin)  )
    23 
    24     # 面向过程写法(普通的函数传参)
    25     def info2(self,name,skin):
    26         print("小孩的姓名是{},小孩的肤色是{}".format(name ,skin)  )
    27 
    28 
    29 wanggangdan = Children("王刚单","综色")
    30 wanggangdan.info1()
    31 wanggangdan.info2("王钢单","白色")
    32 wanggangdan.cry()
    33 
    34 wangtiechui = Children("王铁锤","黑色")
    35 wangtiechui.info1()
    36 wangtiechui.eat()
    37 
    38 wangbaoqiang = Children("王宝强","绿色")
    39 wangbaoqiang.info1()
    40 # wangbaoqiang.__laugh() error
    View Code

    2、__new__ 魔术方法

    触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
    功能:控制对象的创建过程
    参数:至少一个cls接受当前的类,其他根据情况决定
    返回值:通常返回对象或None

     1.基本使用

     1 class OtherClass():
     2     pty = 200
     3 obj2 = OtherClass()
     4 
     5 class MyClass():
     6     pty = 1
     7     def __new__(cls):
     8         print("__new__方法被触发 ... ")
     9         print(cls)
    10         print("<===========>")
    11         
    12         # 返回本类对象 (借父生子)
    13         # 类.方法(cls)
    14         # return object.__new__(cls)
    15         # 不返回对象
    16         # return None
    17         # 返回其他类对象
    18         return obj2
    19 
    20 obj = MyClass()
    21 print(obj)
    22 print(obj.pty)
    View Code

    2.__new__ 和 __init__ 的触发时机

    __new__ 是在造对象时触发
    __init__ 有对象之后,初始化对象的时候自动触发
    先有对象,在初始化;

    3.__new__ 和 __init__ 参数需要一一对应

     1 class MyClass():
     2 
     3     def __new__(cls,name):
     4         print(333)
     5         return object.__new__(cls)
     6     def __init__(self,name):
     7         print(444)
     8         self.name = name
     9         
    10 obj = MyClass("李琦")
    11 print(obj.name)
    12 
    13 # 在__new__中加上收集参数,以不变应万变
    14 class MyClass():
    15     
    16     def __new__(cls,*args,**kwargs):
    17         print(333)
    18         return object.__new__(cls)
    19     def __init__(self,name,sex,age):
    20         print(444)
    21         self.name = name
    22         self.sex = sex
    23         self.age = age
    24 obj = MyClass("朱培峰","女性","100")
    25 print(obj.name)
    26 print(obj.sex)
    27 print(obj.age)
    View Code

    4.注意点

    如果没有创建出对象,不会触发构造方法 ...
    如果返回的不是本类对象,不会触发构造方法 ...

    3、单态(例)模式

    同一个类,无论实例化多少次,都有且只有一个对象

    作用: 可以减少内存空间的浪费,提升代码执行效率
    场景: 如果不需要在创建对象时,在类外额外为当前对象添加成员,就可以使用单态模式;

    (1) 基本使用

     1 class SingleTon():
     2     # 类中私有成员属性
     3     __obj = None
     4     
     5     def __new__(cls):
     6         print(cls) # <class '__main__.SingleTon'>
     7         # 类.私有成员属性
     8         if cls.__obj is None:
     9             # 存储创建的对象在私有成员__obj当中
    10             # 类.私有成员属性 = 值(对象)            
    11             cls.__obj = object.__new__(cls)
    12         # 返回该对象
    13         return cls.__obj
    14         
    15 obj1 = SingleTon()
    16 obj2 = SingleTon()
    17 obj3 = SingleTon()
    18 print(obj1)
    19 print(obj2)
    20 print(obj3)
    View Code

    代码解析:
    obj1 = SingleTon() 触发__new__魔术方法 if cls.__obj is None: 条件满足,创建对象赋值给私有成员__obj return 当前创建的对象
    obj2 = SingleTon() 触发__new__魔术方法 return cls.__obj
    obj3 = SingleTon() 触发__new__魔术方法 return cls.__obj

    (2) 注意点

     1 class SingleTon():
     2     __obj = None
     3     def __new__(cls,*args,**kwargs):
     4         if cls.__obj is None:
     5             cls.__obj = object.__new__(cls)
     6         return cls.__obj
     7     
     8     def __init__(self,name):
     9         self.name = name
    10     
    11 obj1 = SingleTon("王永娟")
    12 obj2 = SingleTon("荷叶")
    13 print(obj1.name) 
    14 print(obj2.name)
    15 
    16 print(obj1,obj2)
    17 print(obj1 is obj2) ##相等 同一地址
    View Code

    4、__del__ 魔术方法(析构方法)

    触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
    功能:对象使用完毕后资源回收
    参数:一个self接受对象
    返回值:无

    1.基本使用

     1 # 1.基本使用
     2 class LangDog():
     3     # 构造方法
     4     def __init__(self,name):
     5         self.name = name
     6         
     7     # 析构方法
     8     def __del__(self):
     9         print("析构方法被触发 ... ")
    10 
    11 # 1.页面执行完毕回收所有变量,自动触发
    12 obj1 = LangDog("小白土狗")
    13 print(obj1.name)
    14 # 2.所有对象被del的时候,自动触发
    15 # print("<==========start==========>")
    16 # del obj1
    17 # print("<==========end==========>")
    18 # 3.注意点
    19 """当一个数据没有任何变量引用的时候,才会真正的被内存释放掉;"""
    20 obj2 = obj1
    21 obj3 = obj1
    22 print(obj2 is obj3)
    23 print(obj1,obj2,obj3)
    24 print("<==========start==========>")
    25 del obj1
    26 del obj2
    27 del obj3
    28 print("<==========end==========>")
    View Code

    2.模拟文件操作

     1 import os
     2 class ReadFile():
     3         
     4     def __new__(cls,filename):
     5         # 判断文件是否存在,在创建对象
     6         if os.path.exists(filename):
     7             return object.__new__(cls)
     8         else:
     9             print("抱歉,该文件不存在")
    10 
    11     def __init__(self,filename):
    12         # 打开文件
    13         self.fp = open(filename,mode="r",encoding="utf-8")
    14         
    15     def readfile(self):
    16         # 读取文件
    17         data = self.fp.read()
    18         return data
    19         
    20     def __del__(self):
    21         # 关闭文件
    22         self.fp.close()
    23 
    24 obj = ReadFile("ceshi1.txt")
    25 # obj = ReadFile("ceshi1.txt234242234423") 文件不存在,不会创建对象
    26 res = obj.readfile()
    27 print(res)
    View Code

    5、__call__ 魔术方法

    触发时机:把对象当作函数调用的时候自动触发

    功能: 模拟函数化操作

    参数: 参数不固定,至少一个self参数

    返回值: 看需求

    (1) 基本用法

    class MyClass():
        def __call__(self):
            print("__call__ 方法被触发 ... ")
            
    obj = MyClass()
    obj()

    (2) 模拟洗衣服的过程

     1 class Wash():
     2     def __call__(self,something):
     3         print("正在{}".format(something))
     4         self.step1()
     5         self.step2()
     6         self.step3()        
     7         return "洗完了"
     8         
     9     def step1(self):
    10         print("脱衣服,把衣服扔进洗衣机")
    11         
    12     def step2(self):
    13         print("扔点蓝月亮,洗衣粉,洗衣皂,金纺... ")
    14         
    15     def step3(self):
    16         print("穿上去,等于晾干")
    17 
    18 obj = Wash()
    19 
    20 # 方法一
    21 # obj.step1()
    22 # obj.step2()
    23 # obj.step3()
    24 
    25 # 方法二
    26 res = obj("洗衣服")
    27 print(res)
    View Code

    (3) 模拟int操作

     1 import math
     2 class MyInt():
     3     def __call__(self,num):
     4         
     5         # 判断是否是布尔类型,做转换
     6         if isinstance(num,bool):
     7             if num == True:
     8                 return 1
     9             else:
    10                 return 0
    11                 
    12         # 判断是否是整型,做转换
    13         elif isinstance(num,int):
    14             return num
    15             
    16         # 判断是否是浮点型,做转换
    17         elif isinstance(num,float):
    18             # 方法一
    19             """
    20             a,b = str(num).split(".")
    21             return eval(a)
    22             """
    23             
    24             # 方法二
    25             """ceil  floor"""
    26             """
    27             if num >= 0:
    28                 return math.floor(num)
    29             else:
    30                 return math.ceil(num)
    31             """
    32                 
    33             # 简写
    34             return math.floor(num) if num >= 0 else math.ceil(num)
    35             
    36         # 判断是否是字符串
    37         elif isinstance(num,str):
    38             # 获取第一为是+或者-,后面全是纯数字,可以转换
    39             if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal():
    40                 # 判定符号
    41                 if num[0] == "+":
    42                     sign = 1
    43                 else:
    44                     sign = -1
    45                 # 计算数据
    46                 return self.calc(num[1:],sign)
    47                 
    48             elif num.isdecimal():
    49                 return self.calc(num)
    50                 
    51             else:
    52                 return "抱歉,这个算不了"
    53             
    54     def calc(self,num,sign=1):
    55         # print("<========================>")
    56         res = num.lstrip("0")
    57         if res == "":
    58             return 0
    59         return eval(res) * sign
    60         
    61         
    62 # int 整型 浮点型 布尔型 纯数字字符串
    63 myint = MyInt()
    64 # 布尔型
    65 res = myint(False)
    66 print(res)
    67 # 整型
    68 res = myint(199)
    69 print(res)
    70 # 浮点型
    71 res = myint(5.77)
    72 res = myint(-5.77)
    73 print(res , type(res))
    74 
    75 # 字符串
    76 # res = myint("-00001111")
    77 
    78 res = myint("asdfasdf") # -1111 ("-000000000000000000000000")
    79 print("<============start============>")
    80 print(res)
    81 print("<============end============>")
    82 
    83 """
    84 print(math.floor(3.15))
    85 print(int(3.15))
    86 
    87 print(math.ceil(-3.15))
    88 print(int(-3.15))
    89 
    90 
    91 print(math.floor(0))
    92 # print(int(0.13))
    93 
    94 """
    95 
    96 print(int("0000000000000000000012121121"))
    97 print(int("+0000000000000000000012121121"))
    98 print(int("-0000000000000000000012121121"))
    View Code

    6、__str__ 魔术方法

    触发时机: 使用print(对象)或者str(对象)的时候触发

    功能:     查看对象

    参数:     一个self接受当前对象

    返回值:   必须返回字符串类型

     1 class Cat():
     2     gift = "抓老鼠"
     3     def __init__(self,name):
     4         self.name = name
     5         
     6     def cat_info(self):
     7         return "小猫名字叫{},天赋是{}".format(self.name,self.gift)
     8         
     9     def __str__(self):
    10         return self.cat_info()
    11     
    12     # (了解) __repr__ = __str__
    13     
    14 tom = Cat("汤姆")
    15 # 第一种触发方式
    16 # print(tom)
    17 # 第二种触发方法
    18 res = str(tom)
    19 print(res)
    20 
    21 
    22 res = repr(tom)
    23 print(res)
    View Code

    7、__repr__ 魔术方法

    触发时机: 使用repr(对象)的时候触发

    功能:     查看对象,与魔术方法__str__相似

    参数:     一个self接受当前对象

    返回值:   必须返回字符串类型

     1 class Mouse():
     2     gift = "遛猫"
     3     
     4     def __init__(self,name):
     5         self.name = name
     6         
     7     def mouse_info(self):
     8         return "老鼠的名字{},天赋是{}".format(self.name,self.gift)
     9         
    10     def __repr__(self):
    11         return self.mouse_info()
    12 
    13     
    14 jerry = Mouse("杰瑞")
    15 res = repr(jerry)
    16 print(res)
    17 
    18 # 在打印或者str(对象) 仍然可以触发__repr__
    19 # 原因: 系统在底层加入了如下语句: __str__ = __repr__
    20 print(jerry)
    21 res = str(jerry)
    22 print(res)
    View Code

    8、__bool__ 魔术方法

    触发时机:使用bool(对象)的时候自动触发

    功能:强转对象

    参数:一个self接受当前对象

    返回值:必须是布尔类型

    类似的还有如下等等(了解):

    __complex__(self)      被complex强转对象时调用

    __int__(self)          被int强转对象时调用

    __float__(self)        被float强转对象时调用

    1 class MyClass():
    2     def __bool__(self):
    3         return False
    4     
    5 obj = MyClass()
    6 # 强转对象时自动触发
    7 print(bool(obj))
    View Code

    9、_add__ 魔术方法  (与之相关的 __radd__ 反向加法)

    触发时机:使用对象进行运算相加的时候自动触发

    功能:对象运算

    参数:二个对象参数

    返回值:运算后的值

    类似的还有如下等等(了解):

    __sub__(self, other)           定义减法的行为:-

    __mul__(self, other)           定义乘法的行为:

    __truediv__(self, other)       定义真除法的行为:

     1 class MyClass():
     2     def __init__(self,num):
     3         self.num = num
     4         
     5     # 对象 在加号的左边,自动触发__add__魔术方法
     6     def __add__(self,other):
     7         print(self) # a
     8         print(other)# 5
     9         return self.num + other # 15
    10         
    11     # 对象 在加号的右边,自动触发__radd__魔术方法
    12     def __radd__(self,other):
    13         print(self) # b
    14         print(other)# 3
    15         return self.num + 2 * other
    16         
    17 # 写法一
    18 a = MyClass(10)
    19 res = a + 5
    20 print(res)
    21 
    22 # 写法二
    23 b = MyClass(5)
    24 res = 3 + b
    25 print(res)
    26 
    27 # 写法三
    28 """
    29 先触发add方法:self => a , other => b return self.num + other => return 10 + b =>   res = 10 + b
    30 再触发radd方法:self => b , other => 10 return 5 + 2 * 10 = 5 + 20 = 25
    31 """
    32 res = a + b
    33 print(res)
    34 
    35 #  25 25 25
    View Code

    10、__len__ 魔术方法

    触发时机:使用len(对象)的时候自动触发 

    功能:用于检测对象中或者类中某个内容的个数

    参数:一个self接受当前对象

    返回值:必须返回整型

     1 class MyClass():
     2     pty1 = 1
     3     pty2 = 2
     4     __pty3 = 3
     5     __pty4 = 3
     6     
     7     def func1():
     8         pass
     9     def func2():
    10         pass
    11     def __func3():
    12         pass
    13     
    14     def __len__(self):
    15         # 基本写法
    16         """
    17         lst = []
    18         print(MyClass.__dict__)
    19         dic = MyClass.__dict__
    20         for i in dic:
    21             print(i,type(i))
    22             if not (i.startswith("__") and i.endswith("__")):
    23                 lst.append(i)
    24         return len(lst)
    25         """
    26                 
    27         # 优化代码
    28         return len([i for i in MyClass.__dict__ if not (i.startswith("__") and i.endswith("__"))])
    29         
    30         
    31 
    32 obj = MyClass()
    33 res = len(obj)
    34 print(res)
    View Code

     六、魔术属性

     1、包含成员及例子

     __dict__ 获取对象或类的内部成员结构
    __doc__ 获取对象或类的内部文档
     __name__ 获取类名函数名
    __class__ 获取当前对象所属的类
     __bases__ 获取一个类直接继承的所有父类,返回元组

     1 class Yeye():
     2     pass
     3     
     4 class Man(Yeye):
     5     pass
     6     
     7 class Woman(Yeye):
     8     pass
     9 
    10 class nalutao(Man,Woman):
    11     """
    12 成员属性:hair , eye
    13 成员方法:yingfenshen __yeyoushu
    14 对类描述:描述漩涡鸣人这个人的相关信息
    15     """
    16 
    17     hair = "金光色"
    18     
    19     eye = "蓝色"
    20     
    21     def yingfenshen(self):
    22         print("使出影分身迷惑敌人")
    23     
    24     def luo_xuan_wan(self,func):
    25         print("使出螺旋丸法术 ... ")
    26         res = func.__name__
    27         print(res , type(res))
    28     
    29     def __yeyoushu(self):
    30         print("使出色诱术勾引敌人 ... ")
    31         
    32 obj = nalutao()
    33 # __dict__ 获取对象或类的内部成员结构
    34 print(obj.__dict__)
    35 print(nalutao.__dict__)
    36 # __doc__  获取对象或类的内部文档
    37 print(obj.__doc__)
    38 print(nalutao.__doc__ )
    39 
    40 # __name__ 获取类名函数名
    41 def abcde():
    42     pass
    43 
    44 obj.luo_xuan_wan(abcde)
    45 
    46 # __class__ 获取当前对象所属的类
    47 print(obj.__class__)
    48 
    49 # __bases__ 获取一个类直接继承的所有父类,返回元组
    50 tup = nalutao.__bases__
    51 print(tup)
    View Code
  • 相关阅读:
    似然函数——likelihood function
    "模式识别与机器学习"读书笔记——1.2 Probability Theory
    "模式识别与机器学习"读书笔记——1.3 Model Selection
    "模式识别与机器学习"读书笔记——1.5 Decision Theory
    C#, XML中有中文加载出错问题的处理
    如何截获浏览器的http请求——几款不错的http抓包工具
    "模式识别与机器学习"读书笔记——2 Probability Distributions
    "模式识别与机器学习"读书笔记——1.6 Information Theory
    基于TCP Socket例子
    黑客介绍跨站攻击工具XSS Shell
  • 原文地址:https://www.cnblogs.com/yj0405/p/14152491.html
Copyright © 2011-2022 走看看