zoukankan      html  css  js  c++  java
  • 026_内置的类方法(双下线方法)

    1, __str__ 和 __repr__

    • obj.__str__  str(obj)    #  %s  str()      直接打印对象 实际上都是走的__str__
    • obj.__repr__ repr(obj)  #  %r  repr()    实际上都是走的__repr__
    • repr 是str的备胎,即调用str时,在命名空间中,如果找不到str方法,但是,有repr方法,就调用repr方法。但str不能做repr的备胎。
    • 都必须返回的是字符串格式。
    • 改变对象的字符串显示 __str__ , __repr__;自定制格式化字符串 __format__
    class Teacher:
        def __init__(self,name,salary):
            self.name = name
            self.salary = salary
        def __str__(self):
            return "Teacher's object :%s"%self.name
        def __repr__(self):
            return str(self.__dict__)
        def func(self):
            return 'wahaha'
    nezha = Teacher('哪吒',250)
    
    # print(nezha)  # 打印一个对象的时候,就是调用 nezha.__str__
    # 所有没有继承的类,默认继承object类,对象中没有就会向object类查找。该方法在object类存在。
    # object  里有一个__str__,一旦被调用,就返回调用这个方法的对象的内存地址。
    
    # print(repr(nezha))   # 执行nezha对象中__repr__()方法
    # print('>>> %r'%nezha) # %r执行nezha对象中__repr__()方法
    

    2,item系列

      __getitem__      __setitem__      __delitem__

    class Foo:
        def __init__(self,name,age,sex):
            self.name = name
            self.age = age
            self.sex = sex
    
        def __getitem__(self, item):
            if hasattr(self,item):
                return self.__dict__[item]
    
        def __setitem__(self, key, value):
            self.__dict__[key] = value
    
        def __delitem__(self, key):
            del self.__dict__[key]
    
    f = Foo('egon',38,'男')
    print(f['name'])     # f['name']执行__getitem__()方法  #>>>egon
    
    f['hobby'] = '男'    #执行__setitem__()方法
    print(f.hobby,f['hobby'])  #>>>男 男
    
    del f.hobby         # object 原生支持  __delattr__,不用调用类里的方法
    print(f.__dict__)
    # del f['hobby']    # 通过自己实现的,执行__delitem__()方法
    # print(f.__dict__)
    

    3,__del__ 

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

        注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

    class A:
        def __del__(self):   # 析构函数: 在删除一个对象之前进行一些收尾工作
            print('执行我了!')
    a = A()
    del a   # del 既执行了__del__()这个方法,又删除了对象   #>>>执行我了!
    
      3.2,在python中,会记录你的变量在程序中会用几次并计数,用一次就会将计数减一,当计数为零时就会自动的帮你把这个变量删除,此时也会执行__del__()方法。
    class A:
        # 析构函数: 在删除一个对象之前进行一些收尾工作
        def __del__(self):
            print('执行我了!')
    
    lst = []
    for i in range(3):
        lst.append(A())  #得到三个变量
        print(i)
    import time
    time.sleep(3)  # 3秒后程序结束将三个变量删除了 
                   #结果打印了三次'执行我了!'

      3.3,使用

        def __del__(self):   # 析构函数: 在删除一个对象之前进行一些收尾工作
            self.f.close()
    a = A()
    a.f = open()   # 打开文件 第一 在操作系统中打开了一个文件 拿到了文件操作符存在了内存中
    del a          # a.f 这个拿到的文件操作符就消失在了内存中,但打开的文件并没有关,因此,会先执行__del__()将文件关闭。

    4,__call__

    class A:
        def __init__(self,name):
            self.name = name
        def __call__(self):
            '''
            打印这个对象中的所有属性
            :return:
            '''
            for k in self.__dict__:
                print(k,self.__dict__[k])
    a = A('alex')()  #“对象()”就是调用__call__()方法。
    

    5, __new__  构造方法 : 创建一个对象

      5.1,

    class A:
        def __init__(self):
            self.x = 1
            print('in init function')
     
        def __new__(cls, *args, **kwargs):
            print('in new function')
            return object.__new__(A, *args, **kwargs)
    #实例化类A时,先执行了__new__()通过object类创建了一个self对象,在执行__init__()

      5.2,单例模式

    • 一个类 始终 只有 一个 实例
    • 当你第一次实例化这个类的时候 就创建一个实例化的对象
    • 当你之后再来实例化的时候 就用之前创建的对象
    class A:
        __instance = False
        def __init__(self,name,age):
            self.name = name
            self.age = age
        def __new__(cls, *args, **kwargs):
            if cls.__instance:
                return cls.__instance
            cls.__instance = object.__new__(cls)
            return cls.__instance
    
    egon = A('egg',38)
    egon.cloth = '小花袄'
    nezha = A('nazha',25)
    print(nezha)
    print(egon)
    print(nezha.name)
    print(egon.name)
    print(nezha.cloth)
    

    6,__len__

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __len__(self):
            return len(self.__dict__)
    a = A()
    print(len(a))
    

    7,__hash__

      只要是可哈希的内部一定实现了一个__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','男')
    

     8,__eq__

    class A:
        def __init__(self,name):
            self.name = name
    
        def __eq__(self, other):
            if self.__dict__ == other.__dict__:  # 不加dict比较的是俩个对象的内存地址。
                return True
            else:
                return False
    
    ob1 = A('egon')
    ob2 = A('egg')
    print(ob1 == ob2)  # ob1 == ob2 调用__eq__()方法。
    

    9,将部分属性一样的判定为是一个对象,怎么做?

      100 名字 和 性别 年龄不同。

     

    class A:
        def __init__(self,name,sex,age):
            self.name = name
            self.sex = sex
            self.age = age
    
        # def __eq__(self, other):        # 需要加上
        #     if self.name == other.name and self.sex == other.sex:
        #         return True
        #     return False
    
        def __hash__(self):
            return hash(self.name + self.sex)
    
    a = A('egg','男',38)
    b = A('egg','男',37)
    print(set((a,b)))   # unhashable
    
    # set 依赖对象的 __hash__     __eq__
    

    10,命名元组

    from collections import namedtuple
    Card = namedtuple('Card',['rank','suit']) #创建一个以Card命名的元组,和内部元素的命名['rank','suit']
    c1 = Card(2,'红心') #创建命名元组对象
    print(c1)  #>>>Card(rank=2,suit='红心')
    print(c1.suit) #>>>红心 
     1 import json
     2 from collections import namedtuple
     3 Card = namedtuple('Card',['rank','suit'])   # rank 牌面的大小 suit牌面的花色
     4 class FranchDeck:
     5     ranks = [str(n) for n in range(2,11)] + list('JQKA')
     6     suits = ['红心','方板','梅花','黑桃']
     7 
     8     def __init__(self):
     9         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
    10                                         for suit in FranchDeck.suits]
    11 #此处相当于:for suit in FranchDeck.suits:
    12 #        for rank in FranchDeck.ranks:
    13 #            Card(rank,suit)
    14  
    15     def __len__(self):
    16         return len(self._cards)
    17 
    18     def __getitem__(self, item):
    19         return self._cards[item]
    20 
    21 deck = FranchDeck()
    22 print(deck[0])  #拿第几张牌
    23 from random import choice
    24 print(choice(deck))  #调用deck中的__len__()
    25 print(choice(deck))
    纸牌游戏
     1 class FranchDeck:
     2     ranks = [str(n) for n in range(2,11)] + list('JQKA')
     3     suits = ['红心','方板','梅花','黑桃']
     4 
     5     def __init__(self):
     6         self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
     7                                         for suit in FranchDeck.suits]
     8 
     9     def __len__(self):
    10         return len(self._cards)
    11 
    12     def __getitem__(self, item):
    13         return self._cards[item]
    14 
    15     def __setitem__(self, key, value):
    16         self._cards[key] = value
    17 
    18 deck = FranchDeck()
    19 print(deck[0])
    20 from random import choice
    21 print(choice(deck))
    22 print(choice(deck))
    23 
    24 from random import shuffle
    25 shuffle(deck)     #洗牌
    26 print(deck[:5]) 
    纸牌游戏2
     1 class Person:
     2     def __init__(self,name,age,sex):
     3         self.name = name
     4         self.age = age
     5         self.sex = sex
     6 
     7     def __hash__(self):
     8         return hash(self.name+self.sex)
     9 
    10     def __eq__(self, other):
    11         if self.name == other.name and self.sex == other.sex:return True
    12 
    13 
    14 p_lst = []
    15 for i in range(84):
    16     p_lst.append(Person('egon',i,'male'))
    17 
    18 print(p_lst)
    19 print(set(p_lst))
    一道面试题

     

  • 相关阅读:
    JAVA面向对象概述
    练习
    字符串
    图形代码
    assets转到内外部存储
    file存储
    sp存储
    Intent练习
    存储登录
    存储
  • 原文地址:https://www.cnblogs.com/eternity-twinkle/p/10644115.html
Copyright © 2011-2022 走看看