Python的魔術方法總結
阿新 • • 發佈:2019-01-12
魔術方法:再不需要程式設計師定義,本身就存在類中的方法就是魔術方法。
魔術方法通常都長這樣:__名字__。
1.__str__和__repr__
為了方便記憶看如下列子
class Course: def __init__(self,name,period,price,teacher): self.name= name self.period = period self.price = price self.teacher = teacher def __str__(self):__str__,__repr__return 'str : %s %s %s %s' % (self.name, self.period, self.price, self.teacher) def __repr__(self): return 'repr : %s %s %s %s' % (self.name, self.period, self.price, self.teacher) course_lst = [] python = Course('python','6 month',29800,'boss jin') course_lst.append(python) linux= Course('linux','5 month',25800,'oldboy') course_lst.append(linux) for id,course in enumerate(course_lst,1): # print('%s %s %s %s %s'%(id,course.name,course.period,course.price,course.teacher)) print(id,course) print('%s %s'%(id,course)) print(str(course)) print(repr(course))print('%r'%course)
__str__觸發條件:
1.當你列印一個物件的時候觸發
2.當你使用%格式化的時候觸發
3.str強轉資料型別的時候觸發
__repr__:
1.__repr__是__str__的備胎
2.有__str__的時候執行__str__,沒有實現__str__的時候,執行__repr__
3.repr(obj)內建函式對應的結果是__repr__的返回值
4.當你使用%r的格式化的時候 觸發__repr__
2.__new__
在init之前,例項化物件的第一步是__new__建立了一個空間
class Foo: def __init__(self): # 初始化方法 print('執行了init') def __new__(cls, *args, **kwargs): # 構造方法 # object.__new__(cls) print('執行了new') return object.__new__(cls) obj = Foo()
創造一個物件比喻成捏小人
new是把小人捏出來
init給小人穿衣服
應用:建立單例模式
class Foo: __instance = None def __init__(self, name, age): # 初始化方法 self.name = name self.age = age self.lst = [name] def __new__(cls, *args, **kwargs): # 構造方法 if cls.__instance is None: cls.__instance = object.__new__(cls) return cls.__instance obj1 = Foo('alex', 20) obj2 = Foo('egon', 22) abc1 = Foo('cao', 33) print(obj1.lst, obj2.lst, abc1.lst)單列模式
3.__del__
物件的__del__是物件在被gc消除回收的時候起作用的一個方法,它的執行一般也就意味著物件不能夠繼續引用。
看如下列子:
class Foo: def __init__(self, name, age): self.name = name self.age = age self.file = open('file', mode='w') def write(self): self.file.write('sjahgkldhgl') def __del__(self): # 析構方法 : 在刪除這個類建立的物件的時候會先觸發這個方法,再刪除物件 # 做一些清理工作,比如說關閉檔案,關閉網路的連結,資料庫的連結 self.file.close() print('執行del了') f = Foo('alex', 20) print(f)__del__
4.__len__
如果一個類表現得像一個list,要獲取有多少個元素,就得用 len() 函式。
要讓 len() 函式工作正常,類必須提供一個特殊方法__len__(),它返回元素的個數。
class A: def __init__(self): self.a = 1 self.b = 2 def __len__(self): return len(self.__dict__) a = A() print(len(a)) print(a.__dict__)
菲波那切數列
# 菲波那切數列 # class Fib(object): # def __init__(self, num): # a, b, L = 0, 1, [] # for n in range(num): # L.append(a) # a, b = b, a + b # self.numbers = L # # def __str__(self): # return str(self.numbers) # # # __repr__ = __str__ # # def __len__(self): # return len(self.numbers) # # # f = Fib(10) # print(f) # print(len(f))菲波那切數列
5.__eq__
__eq__ 當判斷兩個物件的值是否相等時,觸發此方法.
class Staff: def __init__(self,name,sex): self.name = name self.sex = sex def __eq__(self, other): return self.__dict__ == other.__dict__ alex = Staff('alex','不詳') alex2 = Staff('alex','不詳') alex22 = Staff('alex2','female') print(alex == alex2) # alex.__eq__(alex2) print(alex2 == alex22)
6.__call__
物件後面加括號,觸發執行。
class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): print('__call__') obj = Foo() # 執行 __init__ obj() # 執行 __call__
7.__hash__
# 當一個物件的類中有"__hash__"這個方法時, 那麼這個物件就可以執雜湊計算
# 前提是要雜湊的值是可雜湊的. 雜湊的不是物件, 而是可以通過物件直接執行"hash(obj)"
class A: def __init__(self): self.a = 1 self.b = 2 def __hash__(self): return hash(str(self.a)+str(self.b)) a = A() print(hash(a))
8.item系列
__getitem__,__setitem,__delitem__
class Foo: def __init__(self,name): self.name=name def __getitem__(self, item): print(self.__dict__[item]) def __setitem__(self, key, value): self.__dict__[key]=value def __delitem__(self, key): print('del obj[key]時,我執行') self.__dict__.pop(key) def __delattr__(self, item): print('del obj.key時,我執行') self.__dict__.pop(item) f1=Foo('sb') f1['age']=18 f1['age1']=19 del f1.age1 del f1['age'] f1['name']='alex' print(f1.__dict__)item系列