• 二. python面向对象(内置方法and析构函数)


    一. 内置方法和析构函数

     __str__() 在调用print 打印对象时自动调用 是给用户用的 是一个描述对象的方法
        
     __repr__()    是给机器用的在python 解释器里面直接敲对象在回车后调用次方法
    
    对于一个object来说,__str__和__repr__都是返回对object的描述,只是,前一个的描述简短而友好,后一个的描述,更细节复杂一些,
    对于有些数据类型,__repr__返回的是一个string

    优点: 当一个对象属性值很多 并且需要都需要打印 重写了
    __str__方法后简化了代码

    1. __repr__()  方法

    class Apple:
        # 实现构造器
        def __init__(self, color, weight):
            self.color = color;
            self.weight = weight;
        # 重写__repr__方法,用于实现Apple对象的“自我描述”
        def __repr__(self):
            return "Apple[color=" + self.color +
                ", weight=" + str(self.weight) + "]"
    a = Apple("红色" , 5.68)
    # 打印Apple对象
    print(a)  # Apple[color=红色, weight=5.68]
    print(a.__dict__)  # {'color': '红色', 'weight': 5.68}

    2. __str__()方法

    # 创建一个简单的类
    class person(object):
          
           def __init__(self,name,age,height,weight):
            # 定义属性       
             self.name=name
             self.age=age
             self.height=height
             self.weight=weight
           def __str__(self):
             return "%s-%d-%d-%d" % (self.name,self.age,self.height,self.weigh)
    
    per2=person("张三丰",200,165,65)
    # print(per2.name,per2.age,per2.height,per2.weight)  #张三丰 200 165 65kg
    
    print(per2)  #张三丰 200 165 65kg

     3. __len__  ()方法

    # __len__  和 len配合使用
    class Students(object):
        def __init__(self, *args):
            self.names = args
        def __len__(self):
            return len(self.names)
    
    aa=Students("111",222)
    
    print(aa)    # <__main__.Students object at 0x000002E1EBB5D5F8>
    print(len(aa)) # color': '红色', 'weight': 5.68}

    4.__del__()

    # 析构函数(destructor) 与构造函数相反,当对象结束其生命周期时(例如对象所在的函数已调用完毕),系统自动执行析构函数。析构函数往往用来做"清理善后" 的工作
    # (例如在建立对象时用new开辟了一片内存空间,delete会自动调用析构函数后释放内存)。
    
    # 析构函数 :__del__()释放对象自动调用
    class person(object):
        def run(self):
            print("run")
        def __init__(self, name, age, height, weight):
            self.name = name
            self.age = age
            self.height = height
            self.weight = weight
        def __del__(self):
           print("这里是析构函数11111111")
    per = person("张三", 25, 300, 100)
    # 释放对象       就相当于删除了    就不能访问了   这是手动释放
    del per
    
    
    # 在函数里定义的对象会在函数结束时自动释放(删除)  可以减少内存浪费空间
    def fun():
        per2 = person("李四", 1000, 2000, 30000)
        print(per2.name)
    fun()
    
    
    # 这里是析构函数11111111
    # 李四
    # 这里是析构函数11111111
    class Person(object):
       def __init__(self,name):
          self.name = name
       def __del__(self):
           print("实例对象:%s"%self.name,id(self))
           print("python解释器开始回收%s对象了" % self.name)
    
    print("类对象",id(Person))  # 类对象 2052877825944
    
    zhangsan= Person("张三")
    print("实例对象张三:",id(zhangsan))  # 实例对象张三: 2052909816408
    print("------------")
    lisi= Person("李四")
    print("实例对象李四:",id(lisi))  # 实例对象李四: 2052909815232
    
    # 类对象 2052877825944
    # 实例对象张三: 2052909816408
    # ------------
    # 实例对象李四: 2052909815232
    # 实例对象:张三 2052909816408
    # python解释器开始回收张三对象了
    # 实例对象:李四 2052909815232
    # python解释器开始回收李四对象了
    import time
    class Animal(object):
     # 初始化方法
    # 创建完对象后会自动被调用
      def __init__(self, name):
         print('__init__方法被调用')
         self.__name = name
    # 析构方法
    # 当对象被删除时,会自动被调用
      def __del__(self):
        print("__del__方法被调用")
        print("%s对象马上被干掉了..."%self.__name)
    # 创建对象
    dog = Animal("哈皮狗")
    # 删除对象
    del dog
    cat = Animal("波斯猫")
    print(id(cat))
    cat2 = cat
    print(id(cat2))
    cat3 = cat
    print(id(cat3))
    print("---马上 删除cat对象")
    del cat
    print("---马上 删除cat2对象")
    del cat2
    print("---马上 删除cat3对象")
    del cat3
    
    print("程序2秒钟后结束")
    time.sleep(2)
    
    
    # _init__方法被调用
    # __del__方法被调用
    # 哈皮狗对象马上被干掉了...
    # __init__方法被调用
    # 2710758308552
    # 2710758308552
    # 2710758308552
    # ---马上 删除cat对象
    # ---马上 删除cat2对象
    # ---马上 删除cat3对象
    # __del__方法被调用
    # 波斯猫对象马上被干掉了...
    # 程序2秒钟后结束

    5. __call__()

    # __call__
    # 上面我们看到,后面加上括号可以直接调用,我们称之后可调用对象。
    # 类也是一个可调用对象,其调用返回实例,故类对象的类即元类(最著名的是type)也要实现__call__方法。
    # object类没有__call__方法,所以大部分直接继承object类的类所产生的对象不能被调用。(type类虽然也继承了object类,但是其实现了该方法)
    class Person(object):
        def __init__(self, name, gender):
            self.name = name
            self.gender = gender
    
        def __call__(self, friend):
            print ('My name is %s...' % self.name)
            print ('My friend is %s...' % friend)
    
        def aa(self,cc):
            print("111111111111111111111111111111111",cc,self.name)
    
    p = Person('Bob', 'male')
    print(p)
    p("张三")
    # 单看 p('Tim') 你无法确定 p 是一个函数还是一个类实例,所以,在Python中,函数也是对象,对象和函数的区别并不显著。
    p.aa("卧槽")
    # <__main__.Person object at 0x0000020E64D43A90>
    # My name is Bob...
    # My friend is 张三...
    # 111111111111111111111111111111111 卧槽 Bob
    # 区别   没有是call 只能    对象.方法   a.bb()
    class B:
        def __init__(self,name):
          self.name=name
        def bb(self,lover):
            print("111111111111111111111",lover)
    a=B("张三")
    
    a.bb("卧槽!!1")
    
    
    
    # 区别   没有是call 可以    使用对象直接调用方法 a()
    class B:
        def __init__(self,name):
          self.name=name
        def __call__(self,lover):
            print("111111111111111111111",lover)
    a=B("张三")
    
    a("卧槽!!1")

    6.__new__

    # __new__方法只负责创建
    # __init__方法只负责初始化
    # _new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,
    # 可以return父类(通过super(当前类名, cls))__new__出来的实例,或者直接是object的__new__出来的实例

    _new__至少要有一个参数cls,代表要实例化的类,此参数在实例化时由Python解释器自动提供

    
    

    __new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类__new__出来的实例,或者直接是object的__new__出来的实例

    
    

    __init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值


    class Dog(object): def __init__(self,name,age): self.name=name self.age=age print("----init方法-----") def __new__(cls,nice,boy):#cls此时是Dog指向的那个类对象 print("----new方法-----") return object.__new__(cls) dd=Dog("张三","啦啦啦啦啦")
    class ClassA(object):
        def __new__(cls, *args, **kwargs):
            object = super(ClassA, cls).__new__(cls)
            print("in New")
            return object
    
        def __init__(self, *args, **kwargs):
            print("in init")
    
    bb=ClassA()
    # in New
    # in init
    # 可以看出先调用__new__()
    # 再调用 __init__()
    
    print("**************************************")
    
    class ClassA(object):
        def __new__(cls, *args, **kwargs):
            object = super(ClassA, cls).__new__(cls)
            print("in New")
            # return object
    
        def __init__(self, *args, **kwargs):
            print("in init")
    cc=ClassA()
    
    # in New
    
    
    # __new__():真正的构造函数,负责返回实例;
    # __init__():初始化函数,负责在得到实例后进一步初始化一些实例变量。
    # 如果__new__()是类函数,一定会执行;__init__()是实例函数,如果__new__()未返回实例,那么__init__()将没有机会执行。
    # __new__
    class A:
        __aa=False
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __new__(cls, *args, **kwargs):
            if cls.__aa:
                return  cls.__aa
            cls.__aa=object.__new__(A)
            return cls.__aa
    f=A("张三",66666)
    f.cloth="小棉袄"
    g=A("哈哈哈",25)
    print(f)
    print(g)
    print(f.name)
    print(g.name)
    print(g.cloth)
    # __new__ 的作用
    # 1、__new__方法主要是当你继承一些不可变的class时(比如int, str, tuple), 提供给你一个自定义这些类的实例化过程的途径。
    # 假如我们需要一个永远都是正数的整数类型,通过集成int,我们可能会写出这样的代码。
    # 3、__new__必须要有返回值,返回实例化出来的实例,这点在自己实现__new__时要特别注意,可以return父类(通过super(当前类名, cls))
    # __new__出来的实例,或者直接是object的__new__出来的实例
    # 4、__init__有一个参数self,就是这个__new__返回的实例,__init__在__new__的基础上可以完成一些其它初始化的动作,__init__不需要返回值

    7.  __hash__

    # __hash__
    # 返回对象的哈希值,用整数表示。哈希值在字典查找时,可用于快速比较键的值。
    class F(object):
          def __init__(self,name,sex):
              self.name=name
              self.sex=sex
          def __hash__(self):
              return  hash(self.name+ self.sex)
    
    a=F("张三","")
    b=F("张三","1111")
    print(hash(a))
    print(hash(b))
    
    # 337530981586063875
    # 6407353799004837497

    8. __eq__

    # 如果不实现__eq__方法,那么自定义类型会调用默认的__eq__方法, 通过默认方法进行比较的相等条件相当严格,只有自己和自己比才会返回True,表现如下
    # __eq__
    
    
    
    class Item:
      def __init__(self, name):
          self. name=  name
      def __eq__(self, other):
         if self. name== other. name:
             return True
         else:
             return  False
    first = Item('hello')
    second = Item('hello')
    print(first == second) # True
    class A(object):
        def __init__(self, name):
            self.name = name
    
        def __eq__(self, obj):
            return self.name == obj.name
    
    
    a = A("Leon")
    b = A("Leon")
    
    print(a==b) True
    class student(object):
        def __init__(self, name, age, sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __eq__(self, *args, **kwargs):
            return object.__eq__(self, *args, **kwargs)
    
    # python中的对象是否相等有两个层面,一个层面是是否是同一个对象,及在内存中是否共用一个内存区域,用is判断,另一个是对象的值是否相等,用==判断。
    like = student("like", 25, "male")
    xue = student("xue", 23, "female")
    dong = student("like", 25, "male")
    
    print(like is xue)  # False
    print(like is dong)  # False
    print(like == dong)  # False
    
    
    class student(object):
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
        def __eq__(self,other):
            return self.name == other.name
    
    like = student("like",25,"male")
    dong = student("like",23,"female")
    print(like == dong) #True
  • 相关阅读:
    hdu4734 F(x)
    hdu2089 不要62 两解
    luogu2602 [ZJOI2010]数字计数 两解
    lemon
    UVA1218 完美的服务 Perfect Service
    luogu HNOI2003消防局的设立
    uva10891 game of sum
    uva10635 Prince and Princess
    UVA1394 And Then There Was One
    uva10003切木棍
  • 原文地址:https://www.cnblogs.com/Sup-to/p/10873114.html
Copyright © 2020-2023  润新知