1,包內部不要去嘗試應用使用相對導入,必定不會成功的,他不支持這個機制,包內導入時必定要用絕對導入python
2,複習接口類,抽象類,Python中沒有接口類,有抽象類,抽象類是經過abc模塊中的metaclass = ABCMeta 和@abstractmethod實現的git
3,接口類和抽象類本質是作代碼規範用的,我但願在子類中實現和父類方法名徹底同樣的方法編程
4,兩者區別,在JAVA的角度看是有區別的,JAVA沒有多繼承,因此爲了接口隔離原則,就設計了接口這個概念,支持多繼承;JAVA原本就支持單繼承,因此就有了抽象類。Python中既支持單繼承,也支持多繼承,因此對於接口類和抽象類的區別就不那麼明顯了。甚至在Python中根本沒有接口類,可是Python的擴展模塊中有一個模塊確實實現了接口類的概念,因此不能說根本沒有,只是內置模塊中沒有,沒有內置接口類。網絡
5,多態和鴨子類型,多態---Python天生支持多態,給子類找個爸爸,傳爸爸的參數,Python裏面崇尚鴨子類型,不依賴父類的狀況下,實現兩個類中的同名方法。app
6,封裝 ---私有的,在Python中只要__名字,就把這個名字私有化了,私有化以後,就不能從類的外部直接調用了,能夠私有的有靜態屬性方法,對象的屬性均可以私有化,這種私有化只是從代碼級別作了變形,並無真的約束,變形機制 _類名__方法。在類外用這個調用,在類的外部__名字調用。函數
7,私有屬性spa
class Room: def __init__(self,name,length,width): self.name = name self.__length =length self.__width = width def area(self): return self.__length * self.__width jin = Room('jin',3,5) print(jin.area()) jin.name = 'lisa' print(jin.name)
8,get set 方法保護屬性不被修改,私有屬性的查看方法設計
class Room: def __init__(self,name,length,width): self.__name = name self.__length =length self.__width = width def get_name(self): return self.__name # 對私有對象的保護 def set_name(self,new_name): if type(new_name) is str and new_name.isdigit() == False: self.__name = new_name else: print('invalid name') def area(self): return self.__length * self.__width jin = Room('jin',3,5) jin.name = '2' # 不是私有的話,能夠隨便改,要想辦法約束一下 print(jin.name) jin.set_name('lisa') print(jin.get_name()) # C++ 裏面全部的屬性都設置成私有的,
9,父類的私有屬性能夠被子類調用嗎?否代碼規範
class Foo: __key = '123' _Foo__key class Son(Foo): print(Foo.__key) #_Son__key # 此句報錯,因爲不能夠調用
# AttributeError: type object 'Foo' has no attribute '_Son__key
10,總結:會用到私有概念的場景,隱藏起一個屬性,不想讓類的外部調用;我想保護這個屬性,不想讓屬性隨意被改變;我想保護這個屬性不被子類繼承code
11,以前老師欠着的三個內置函數:property,classmethod,staticmethod
12,property,內置裝飾器函數,只在面向對象中使用,可是做爲一個property屬性,函數後面不能傳遞任何參數
from math import pi class Circle: def __init__(self,r): self.r = r @property def perimeter(self): return 2 *pi *self.r @property def area(self): return self.r**2*pi c1 = Circle(5) # print(c1.area()) # 面積不是動做,是一個屬性才合理,如何假裝成一個屬性呢? print(c1.area) print(c1.perimeter) # c1.area = 70 # 不支持賦值
13,BMI指數,方法假裝的屬性,不被容許修改,怎麼辦?
class Person: def __init__(self,name,high,weight): self.name = name self.high = high self.weigh = weight # self.bmi = wight / (high **2) # 這樣寫雖然能夠,可是不規範,操做屬性的方法咱們都是會在方法裏面來寫,各司其職,才更合理 @property def bmi(self): return self.weigh/self.high**2 jin = Person('jin',1.75,70) # print(jin.bmi()) print(jin.bmi) jin.name = 'tiger' # jin.bmi = '23' # 不容許修改,怎麼辦?
14,方法一,name.setter 和 name.deleter
class Person: def __init__(self,name): self.__name = name @property def name(self): return self.__name + ' nb' @name.setter def name(self,new_name): # 雖然是同名函數,可是不會覆蓋 self.__name = new_name @name.deleter def name(self):pass # 裏面不實現的話,是沒有辦法刪除的def self.name tiger = Person('tiger') # print(tiger.name()) # tigernb,另外改爲property以後就不能夠這樣覅用了 print(tiger.name) tiger.name = 'all students' # 沒法修改怎麼辦?再定義一個函數 print(tiger.name) del tiger.name # 刪除屬性 print(tiger.name) # 注意三個函數的名字必須同樣,而且必定要有一個@property方法,才能夠有後面兩個
15,和類屬性的結合
class Goods: discount = 0.8 def __init__(self,name,price): self.name = name self.__price = price # 私有價格,只有本身知道 @property def price(self): return self.__price * Goods.discount apple = Goods('apple',5) print(apple.price)
16,staticmethod 靜態的方法 三顆星,classmethod 類方法 四顆星,property 四星半,重要程度,私有屬性,五顆星
17,classmethod ,把一個方法 變成一個類中的方法,這個方法就能夠直接被類調用,不被須要依託於任何對象
class Goods: __discount = 0.8 def __init__(self,name,price): self.name = name self.__price = price @property def price(self): return self.__price * Goods.__discount @classmethod def change_discount(cls,new_discount): # 去掉self,咱們不推薦這樣寫,標準寫法,不要寫成其餘的 cls.__discount = new_discount # apple = Goods('apple',5) # print(apple.price) # 這個折扣修改的動做,咱們如何不本身來完成,而是用一個函數來完成? # 若是咱們定義成一個對象函數,那麼我必須拿一個對象來進行折扣的修改,可是這個折扣是類屬性,我但願全部的對象都自動修改 # 而不是經過某一個 # apple.change_discount(0.7) Goods.change_discount(0.9) # 當這個方法的操做只涉及靜態屬性的時候,就應該使用classmethod
18,staticmethod,若是一個函數自己和類和對象都沒有什麼關係,可是我就想把這個函數寫入到類裏面,想象春面向對象的語言,例如JAVA,C#
class Login: def __init__(self,name,password): self.name = name self.pwd = password def login(self):pass @staticmethod # 不須要和類和對象產生任何關係,可是還能夠放在類裏面 def get_usr_pwd(): # 必須把它扔進類裏面,纔是面向對象 input('input usrname:') input('input password:') l = Login('alex','3714') l.get_usr_pwd() # 靜態方法既能夠被對象來訪問,也能夠用類來訪問 Login.get_usr_pwd() # 什麼時候使用靜態方法 # 在徹底面向對象的程序中,若是一個函數,既和對象沒有關係,也和類沒有關係,那麼就用staticmethod將這個函數編程一個靜態方法 # 類方法和靜態方法都是類來調用的,那麼對象能夠調用嗎? # 能夠的,想象對象能夠調用靜態屬性嗎?同樣的道理,可是通常狀況下,推薦用類名來調用 # 類方法,有一個默認參數 cls 表明這個類 # 靜態方法,沒有默認參數,就像函數同樣
19,反射,很是重要,五顆星,把字符串當變量使用
# name = 'lisa' # 'name' class Teacher: dic = {'show stu info','show teacher info'} def show_student(self): print('show student') def show_teacher(self): print('show teacher') # menu = Teacher.dic # for k in menu: # print(k) 'dic' # 最後三個內置函數 # hasattr # getattr # defattr ret = getattr(Teacher,'dic') # 左右對應 Teacher.dic print(ret) # {'show stu info', 'show teacher info'} # python中一切皆是對象,包括類和模塊
20,反射類屬性和類方法
class Teacher: dic = {'show stu info','show teacher info'} def show_student(self): print('show student') def show_teacher(self): print('show teacher') @classmethod def func(cls): print('hahaha') ret = getattr(Teacher,'dic') # 左右對應 Teacher.dic,類.屬性 print(ret) # {'show stu info', 'show teacher info'} ret2 = getattr(Teacher,'func') ret2() # hahaha if hasattr(Teacher,'func2'): ret = getattr(Teacher,'func') ret() if hasattr(Teacher,'dic'): ret = getattr(Teacher,'dic') print(ret)
21,反射對象方法
# 反射對象函數 lisa = Teacher() func = getattr(lisa,'show_student') func()
22,使用實例,有了反射我就不用去一條條判斷了,我只須要一條反射,去掉用相應的方法就好了,反射的妙用
for k in Teacher.dic: print(k) key = input("輸入需求:") # print(Teacher.dic[key]) # 這個地方好在不須要去判斷if key = 1 怎麼樣,key =2怎麼樣,用反射,程序自動就去調用了 if hasattr(lisa,Teacher.dic[key]): func = getattr(lisa,Teacher.dic[key]) func()
23,反射很是的重要,也許如今只在面向對象這兒還體會不到他的好,可是到了之後網絡編程,文件操做的時候,會用的很是多
24,經過反射能夠對象名獲取對象屬性和普通方法,類名獲取靜態屬性和類方法和靜態方法
25,面向對象思惟導圖和計算器做業先欠着,後補