• python--类方法


    类方法--双下方法:与内置函数有千丝万缕的关系
    一、改变对象的字符串显示__str__,__repr__
    obj.__str__     类似str(obj)
    obj.__repr__ 类似repr(obj)
        def __init__(self,name):
            self.name=name
        def __str__(self):
            return '她是%s'%self.name        # str 执行的必须是字符串形式
        def __repr__(self):
            return str(self.__dict__)           # repr执行的必须是字符串形式
    teacher=Person('teacher')
    #第一种调用方法
    print(teacher)             #她是teacher   打印一个对象的时候,就是调用a.__str__
    print(repr(teacher))     #{'name': 'teacher'}  调用a.__repr__
    #第二种调用方法
    print('%s'%teacher)     #她是teacher           相当于执行了双下str方法
    print('%r'%teacher)     #{'name': 'teacher'}     相当于执行了双下repr方法
    #第三种调用方法
    print(str(teacher))   #她是teacher   相当于触发了__str__方法
    print(repr(teacher))    #{'name': 'teacher'}  相当于触发了__repr__方法
    class B:
         def __str__(self):
             return 'str : class B'
         def __repr__(self):
             return 'repr : class B'
    b=B()
    print('%s'%b)       #str : class B
    print('%r'%b)         #repr : class B
    练习
    """
    object  里有一个__str__内置方法,一旦被调用,就返回调用这个方法对象的内存地址
    打印一个对象的时候,就是调用a.__str__
    # %s str()  直接打印 实际上都是走的__str__
    # %r repr()  实际上都是走的__repr__
    print(obj)/'%s'%obj/str(obj)的时候,实际上是内部调用了obj.__str__方法,如果str方法有,那么他返回的必定是一个字符串
    如果没有__str__方法,会先找本类中的__repr__方法,再没有再找父类中的__str__。
    repr(),只会找__repr__,如果没有找父类的
    """
    class  Person:
        def __init__(self,name):
            self.name=name
    
        def __repr__(self):
            return str(self.__dict__)
    teacher=Person('teacher')
    print(teacher)    #{'name': 'teacher'}  这时候没有双下str, 会执行repr方法,
    #注释:repr 是str的备胎,但str不能做repr的备胎
    #备胎顺序:当类没有继承其他;类,直接继承object祖类则  备胎顺序是:自己的str--->自己的repr--->祖类的str--->祖类的repr
    # 当类继承的有其他类的话顺序是:自己的str--->继承类的str--->自己的repr--->继承类的repr--->祖类的str--->祖类的repr

    二、析构方法,当对象在内存中被释放时,自动触发执行。

    __del__    del 对象  就触发了
    class A:
        def __del__(self):
            print('执行我啦')
    a=A()
    del a            #先触发执行了__del__,再删除了a
    print(a)         #删除后再打印会报错
    __del__
    析构函数: 在删除一个对象之前进行一些收尾工作
    class B:
        def __del__(self):
            self.f.close()
    b=B()
    b.f=open('uerseinfo',mode='w',encoding='utf-8')
    b.f.write('zxc')        #在文件里写入了zxc
    del b                     #b.f 拿到了文件操作符消失在了内存中
    三、__call__   对象后面加括号,触发执行。*****
    注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;
    而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
    class C:
        def __init__(self,name):
            self.name=name
        def __call__(self):
            for k in self.__dict__:
                print(k+':',self.__dict__[k])
    c = C('zxc')
    a=C('zxc')()        #name: zxc
    c()                     #name: zxc
    __len__    len()触发执行__len__
    class A:
        def __init__(self,name,love):
            self.dog= name
            self.zxc= love
    
        def __len__(self):
            return len(self.__dict__)
    a = A('zxc','pig')
    b=A('zxc','dog')
    print(a.__dict__)    #{'zxc': 'pig', 'dog': 'zxc'}
    print(len(a.__dict__))    #2
    __eq__
    class D:
        def __init__(self,name,love):
            self.name= name
            self.love= love
        def __eq__(self, other):
            if self.name==other.name:
                return True
            else:
                return False
    a=D('zxc','pig')
    b=D('zxc','dog')
    print(a==b)     #True
    __hash__
    class A:
        def __init__(self,name,sex):
            self.name = name
            self.sex = sex
        def __hash__(self):
            return hash(self.name+self.sex)
    a = A('egon','')
    b = A('egon','nv')
    print(hash(a))      #-211948449
    print(hash(b))      #959576532
    __new__  ******
    __new__执行先于__init__中的内容 ,并且在实例化的时候自动执行
    class New:
        def __init__(self,name):
            self.name=name
            print('in init funcing')
        def __new__(cls, *args, **kwargs):
            print( 'in new funcing')
            return object.__new__( New)
    a1=New('zxc')   #in new funcing   最先打印的是__new__方法.再打印in init funcing
    print(a1)        #<__main__.New object at 0x01D4EAD0>
    print(a1.name)      #zxc
     __new__进阶:23种设计模式中很简单的一个:单例模式,核心思想就是__new__
     单例模式特点:
    """
    一个类 始终 只有 一个 实例
    当你第一次实例化这个类的时候 就创建一个实例化的对象
    当你之后再来实例化的时候 就用之前创建的对象
    """
    #注释:一旦有任何修改,都会还是对原来的那个进行重新赋值,并且覆盖之前的实例,从始至终只有一个实例 
    class New:
        __flag=False
        def __init__(self,name,sex):
            self.name=name
            self.sex=sex
        def __new__(cls, *args, **kwargs):
            if cls.__flag:
                return cls.__flag
            cls.__flag=object.__new__(cls)
            return cls.__flag
    a=New('zxc',38)
    print(a.name)   #zxc
    b=New('zzy',18)
    print(a.name)   #zzy
    a.cloth='花裙子'
    print(b.cloth)   #花裙子
    单例
    item系列
    __getitem__\__setitem__\__delitem__
    class Item:
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __getitem__(self, item):
            if hasattr(self,item):
                return self.__dict__[item]
            else:
                return 1
        def __setitem__(self, key, value):
            self.__dict__[key]=value
        def __delitem__(self, key):
            del self.__dict__[key]
    i=Item('zxc',38)
    两种方法查,其实内部机制一样
    print(i.name)        # zxc
    print(i['name'])     # zxc
    两种方法改,其实内部机制一样
    i['name']='zzxxcc'
    print(i.name)          ##zzxxcc
    i.__dict__['name']='stupd_zxc'
    print(i.name)          #stupd_zxc
    两种方法删除,其实内部机制一样
    del i['name']
    print(i['name'])     #1 这种查询方法,虽然找不到,但是不像普通字典那样会报错,这里返回1,
     因为程序里有__getitem__  打印i['name']时候,会先执行__getitem__方法,找item,因为name被删除了,所以就找不到返回'1'
    del i.name        #object 原生支持  __delattr__
    print(i.name)    #这种删除会报错
    #也可以查看一下对象中的内容,看看有没有被删除
    print(i.__dict__)      # {'age': 38}
    进阶
    import json
    from collections import namedtuple
    Card = namedtuple('Card',['rank','suit'])   # rank 牌面的大小 suit牌面的花色
    class FranchDeck:
        ranks = [str(n) for n in range(2,11)] + list('JQKA')   # 2-A
        suits = ['红心','方板','梅花','黑桃']
        def __init__(self):
            self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
                                            for suit in FranchDeck.suits]
        def __len__(self):
            return len(self._cards)
        def __getitem__(self, item):
            return self._cards[item]
        def __setitem__(self, key, value):
            self._cards[key] = value
        def __str__(self):
            return json.dumps(self._cards,ensure_ascii=False)
    deck = FranchDeck()
    print(deck[10])
    from random import choice
    print(choice(deck))
    # print(choice(deck))
    from random import shuffle
    shuffle(deck)
    print(deck[10])
    print(deck)
    print(deck[:5])
    扑克牌
  • 相关阅读:
    oracle 11.2.0.4 ADG+linux+补丁升级11.2.0.4.181016(28204707)
    审计信息清理及审计表迁移时遇到的坑
    与其他schema下表同名视图实验
    Oracle 11gr2 RAC到单实例的DG搭建(落地备份)
    Oracle数据文件名乱码问题
    Vmware12+centos7:固定IP
    Vmware12+OracleLinux5.4+Oracle 11.2.0.3+ASM
    OracleLinux文件名最后带空格生成了新的文件???
    OGG新增DataPump进程下发(多个进程共用队列文件)
    OGG BIGDATA从版本12.2升级到12.3.2.1.1
  • 原文地址:https://www.cnblogs.com/zzy-9318/p/8358031.html
Copyright © 2020-2023  润新知