026_內置的類方法(雙下線方法)

1, __str__ 和 __repr__python

  • 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__ json

  3.1,析構方法,當對象在內存中被釋放時,自動觸發執行。app

    注:此方法通常無須定義,由於Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,由於此工做都是交給Python解釋器來執行,因此,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。dom

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,使用ide

    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__  構造方法 : 建立一個對象ui

  5.1,spa

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))
一道面試題
相關文章
相關標籤/搜索