gj4 深入类和对象
生活随笔
收集整理的這篇文章主要介紹了
gj4 深入类和对象
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
4.1 鴨子類型和多態(tài)
當看到一只鳥走起來像鴨子、游永起來像鴨子、叫起來也像鴨子,那么這只鳥就可以被稱為鴨子
只要利用Python的魔法函數(shù),就能實現(xiàn)某些Python數(shù)據(jù)類型的類似的方法。
class Cat(object):def say(self):print("i am a cat")class Dog(object):def say(self):print("i am a fish") class Duck(object):def say(self):print("i am a duck")animal_list=[Cat,Dog,Duck] for animal in animal_list:animal().say()# 不同的對象實現(xiàn)了相同的方法,多態(tài)i am a cat i am a fish i am a duck ---a = ["lewen1", "lewen2"] b = ["lewen2", "lewen"] name_tuple = ["lewen3", "lewen4"] name_set = set() name_set.add("lewen5") name_set.add("lewen6") a.extend(name_set) # extend() 括號里面為可迭代對象 print(a)['lewen1', 'lewen2', 'lewen6', 'lewen5'] ---class Company(object):def __init__(self, employee_list):self.employee = employee_listdef __getitem__(self, item):return self.employee[item]def __len__(self):return len(self.employee)company = Company(["tom", "bob", "jane"]) b.extend(company) # 可以接受 print(b)['lewen2', 'lewen', 'tom', 'bob', 'jane']
?? 4.2 抽象基類(abc模塊)
e
4.3 使用isintance而不是type
class A:pass ? class B(A):pass ? b = B() ? print(isinstance(b, B)) print(isinstance(b, A)) ? print(type(b)) print(type(b) is B) # is 去判斷兩個對象是不是一個對象, print(type(b) == B) # == 是對值是否相等的判斷 print(type(b) is A) print(isinstance(b, A)) True True <class '__main__.B'> True True False True 盡量使用isinstance 而不是type去判斷一個類型isinstance 返回一個對象是否是類或其子類的一個實例。(Return whether an object is an instance of a class or of a subclass thereof)type 對象的類型4.4 類變量和對象變量
class A:aa = 1 # 類變量def __init__(self, x, y):self.x = x # 實例變量self.y = ya = A(2,3)A.aa = 11 # 修改類變量 a.aa = 100 # 將值賦給實例變量 print(a.x, a.y, a.aa)print(A.aa)b = A(3,5) print(b.aa) --- 2 3 100 11 114.5 類屬性和實例屬性以及查找順序
深度優(yōu)先
這種深度優(yōu)先就不再合理,如果C重載了D的方法,而找了B直接找D,C就沒有用了
再Python3以后修改了這種搜索,為廣度優(yōu)先
C和D有重名的話,理應找完B再找D,而廣度優(yōu)先就會使C覆蓋掉D
Python3 都是采用的深度優(yōu)先
#C3算法
小結(jié):py3 有共同父類(菱形)的廣度優(yōu)先,沒有共同父類的深度優(yōu)先
4.6 靜態(tài)方法、類方法以及對象方法
class Date:#構(gòu)造函數(shù)def __init__(self, year, month, day):self.year = yearself.month = monthself.day = daydef tomorrow(self):self.day += 1#靜態(tài)方法 @staticmethoddef parse_from_string(date_str):year, month, day = tuple(date_str.split("-"))return Date(int(year), int(month), int(day))#硬編碼的方式,只要類名修改,這反回的類名就得修改#類方法@classmethoddef from_string(cls, date_str):year, month, day = tuple(date_str.split("-"))return cls(int(year), int(month), int(day))# 判斷是否是合法的字符串,不需要反回函數(shù)@staticmethoddef valid_str(date_str):year, month, day = tuple(date_str.split("-"))if int(year)>0 and (int(month) >0 and int(month)<=12) and (int(day) >0 and int(day)<=31):return Trueelse:return Falsedef __str__(self):return "{year}/{month}/{day}".format(year=self.year, month=self.month, day=self.day) ? if __name__ == "__main__":new_day = Date(2018, 12, 31)new_day.tomorrow()print(new_day) 2018/12/32#2018-12-31date_str = "2018-12-31"year, month, day = tuple(date_str.split("-"))new_day = Date(int(year), int(month), int(day))print (new_day)#用staticmethod(靜態(tài)方法)完成初始化new_day = Date.parse_from_string(date_str)print (new_day)#用classmethod完成初始化new_day = Date.from_string(date_str)print(new_day) ?print(Date.valid_str("2018-12-32")) 2018/12/31 2018/12/31 2018/12/31 False ? ?4.7 數(shù)據(jù)封裝和私有屬性
class User:def __init__(self, birthyear):self.__birthyear = birthyear # 雙下劃線def get_age(self):# 返回年齡return 2018 - self.__birthyearif __name__ == "__main__":user = User(1990)print(user.get_age())# print(user.__birthyear) # 私有屬性是無法通過,實例訪問的print(user._User__birthyear) # 雙下劃線并不是絕對安全的 """ 28 1990 """4.8 python對象的自省機制
#自省是通過一定的機制查詢到對象的內(nèi)部結(jié)構(gòu) ? class Person:name = "user" ? class Student(Person):def __init__(self, scool_name):self.scool_name = scool_name ? ? user = Student("慕課網(wǎng)") #通過__dict__查詢屬性 print(user.__dict__) #--- {'scool_name': '慕課網(wǎng)'} #--- user.__dict__["school_addr"] = "北京市" print(user.school_addr) #--- 北京市 #--- print(Person.__dict__) print(user.name) #--- {'__module__': '__main__', 'name': 'user', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>, '__doc__': None} user #--- a = [1,2] print(dir(a)) #--- ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']4.9 super函數(shù)
class A:def __init__(self):print ("A") ? class B(A):def __init__(self):print ("B")#super(B,self).__init__() # py2中的寫法super().__init__() ? b = B() #--- B A 既然我們重寫B(tài)的構(gòu)造函數(shù), 為什么還要去調(diào)用super? super到底執(zhí)行順序是什么樣的?from threading import Thread class MyThread(Thread):def __init__(self, name, user):self.user = usersuper().__init__(name=name) # 重用父類的代碼class A:def __init__(self):print ("A") ? class B(A):def __init__(self):print ("B")super().__init__() ? class C(A):def __init__(self):print ("C")super().__init__()class D(B, C):def __init__(self):print ("D")super(D, self).__init__() ? if __name__ == "__main__":print(D.__mro__)d = D() ? # 有共同父類,廣度優(yōu)先 (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>) D B C Asuper() 調(diào)用的順序是mro的順序4.10 django rest framework中對多繼承使用的經(jīng)驗
mixin(混合繼承)模式特點
1. Mixin類功能單一(一個mixin實現(xiàn)一個功能)
2. 不和基類關聯(lián),可以和任意基類組合。 基類可以不和mixin關聯(lián)就能初始化成功
3. 在mixin中不要使用super這種用法
django中一個類繼承多個mixin類實現(xiàn)多個功能
??4.11 python中的with語句
try:print ("code started")raise KeyError except KeyError as e:print ("key error") else: #沒有拋異常才會運行 elseprint ("other error") finally: # 不管有沒有異常,最后會執(zhí)行print ("finally") # 資源的釋放# --- code started key error finally # --- def exe_try():try:print ("code started")raise KeyErrorreturn 1except KeyError as e:print ("key error")return 2else:print ("other error")return 3finally:print ("finally")return 4 # 有返回值會反回,沒有反回上一層的返回值 exe_try() # --- code started key error finally 4 # --- # 上下文管理器協(xié)議, 由 __enter__,__exit__ 實現(xiàn) # with 支持上下文管理器協(xié)議 class Sample:def __enter__(self):print ("enter")#獲取資源return selfdef __exit__(self, exc_type, exc_val, exc_tb):#釋放資源print ("exit")def do_something(self):print ("doing something") ? with Sample() as sample:sample.do_something()# --- enter doing something exit ?4.12 contextlib實現(xiàn)上下文管理器
import contextlib #上下文管理器 @contextlib.contextmanager # 用裝飾器,將一個函數(shù)變成上下文管理器 def file_open(file_name):print ("file open")yield {} # 必須是生成器print ("file end")with file_open("lewen.txt") as f_opened:print ("file processing")--- file open file processing file end ---Python 本身沒有接口,利用魔法函數(shù)的組合,和協(xié)議實現(xiàn)某些數(shù)據(jù)類型的屬性
總結(jié)
以上是生活随笔為你收集整理的gj4 深入类和对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: gj3 Python数据模型(魔法函数)
- 下一篇: gj5 自定义序列类