python继承实现原理封装property
---恢復內容開始---
在Python中繼承順序有兩種:深度優先和廣度優先
沒有共同父類的繼承:
?
class E:def test(self):print('from E') class A(E): #步驟4 A(E) #from E# def test(self):# print('from A') #步驟2 from Bpass class B:# def test(self):# print('from B') #步驟3 from Cpass class C:# def test(self):# print('from C')pass class D(A,B,C):# def test(self):# print('from D') #步驟1 from Apass t=D() #實例化對象t t.test()這種類型的繼承新式類和經典類的順序是一樣的都是深度優先:D--->A--->E--->B--->C
共同父類的繼承
class D(object):def test(self):print('from D')# pass class C(D):def test(self):print('from C')# pass class B(C):def test(self):print('from B')# pass class F(D):def test(self):print('from F')# pass class E(F):def test(self):print('from E')# pass class H(D):def test(self):print('from H')# pass class G(H):def test(self):print('from G')# passclass A(B,E,G):def test(self):print('from A')# pass obj=A() obj.test() print(A.mro()) #經典類不繼承object class D:def test(self):print('from D')# pass class C(D):def test(self):print('from C')# pass class B(C):def test(self):print('from B')# pass class F(D):def test(self):print('from F')# pass class E(F):def test(self):print('from E')# pass class H(D):def test(self):print('from H')# pass class G(H):def test(self):print('from G')# passclass A(B,E,G):def test(self):print('from A')# pass obj=A() obj.test()在這種類型繼承下新式類和經典類的順序不同。
新式類采取廣度優先:A--->B--->C--->E--->F--->G--->H--->D--->object
經典類(python2中才有經典類的概念,python3中都是新式類)使用的是深度優先的方式A--->B--->C--->D--->E--->F--->G
mro():
只有新式類才具有的方法
print(A.mro()) 執行結果 [<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.F'>, <class '__main__.G'>,<class '__main__.H'>, <class '__main__.D'>, <class 'object'>]
可以通過該方法來查看父類的繼承順序
子類調用父類的兩種方法:
class People:def __init__(self,name,age,sex):self.name=nameself.age=ageself.sex=sexdef foo(self):print('from parent')class Teacher(People):def __init__(self,name,age,sex,level,salary):# People.__init__(self,name,age,sex) #方法一super().__init__(name,age,sex) #super(Teacher,self).__init__(name,age,sex) #方法二self.level=levelself.salary=salarydef foo(self):super().foo()print('from child')封裝
封裝是一種隱藏的方式,包括數據封裝和功能封裝,即類里的數據屬性和功能屬性,隱藏數據和功能是為了限制直接調用,通過人為的添加調用接口進行數據和功能的調用
封裝的變形操作只在類的定義階段或者對象的實例化階段
封裝的主要原因:
1.保護隱私
2.隔離復雜度,提供簡單的接口
class Teacher:def __init__(self,name,salary):self.name=nameself.__salary=salarydef foo(self):print('balabala',self.__salary)t=Teacher('xiaolan',5000) print(t.salary) 執行結果 AttributeError: 'Teacher' object has no attribute 'salary' print(t.__dict__) print(t._Teacher__salary) t.foo() 執行結果 {'name': 'xiaolan', '_Teacher__salary': 5000} 5000 balabala 5000 class A:def foo(self):print('from A.foo')self.__bar()def __bar(self):print('from A.bar')class B(A):def bar(self):print('from B.bar')pass b=B() b.foo() 執行結果 from A.foo from A.bar在封裝后對象的數據屬性和函數屬性以‘_類名__屬性’名的形式保存
class Foo:def __func(self): #_Foo__funcprint('from Foo')class Bar(Foo):def __func(self): #_Bar__funcprint('from Bar') b=Bar() b._Foo__func() b._Bar__func()在父類和子類有相同的屬性時不會擔心子類的屬性將父類的屬性覆蓋調用
class People:def __init__(self,name,age,sex,height,weight):self.__name=nameself.__age=ageself.__sex=sexself.__height=heightself.__weight=weight #name、age、sex、height、weight都是經過封裝后保存,所以外部調用的時候沒辦法直接調用def tell_name(self):print(self.__name) #通過手動創建接口的方式返回name的內容,屏蔽了直接調用def set_name(self,val):if not isinstance(val,str):raise TypeError('type must be str')self.__name=val #通過手動創建修改接口修改name的屬性值,屏蔽了直接調用def tell_info(self):print('''---------%s infoname:%sage:%ssex:%sheight:%sweight:%s''' %(self.__name,self.__name,self.__age,self.__sex,self.__height,self.__weight)) #通過手動創建接口,展示所有的信息property:封裝的特性之一
property是一種特殊的屬性,訪問它時會執行一段功能(函數)然后返回值,可以講函數功能的執行偽裝為數據屬性
property的構造方法中有個四個參數
- 第一個參數是方法名,調用?對象.屬性?時自動觸發執行方法
- 第二個參數是方法名,調用?對象.屬性 = XXX?時自動觸發執行方法
- 第三個參數是方法名,調用?del 對象.屬性?時自動觸發執行方法
- 第四個參數是字符串,調用?對象.屬性.__doc__?,此參數是該屬性的描述信息
print(xiaobai.bmi)
執行結果
20.679012345679013 class People:def __init__(self,name,age,sex,height,weight,permission=False):self.__name=nameself.__age=ageself.__sex=sexself.__height=heightself.__weight=weightself.permission=permission@propertydef name(self):return self.__name@name.setter #支持obj.name='NAME'的方式執行def name(self,val):if not isinstance(val,str):raise TypeError('must be str')self.__name=val@name.deleter #支持del刪除操作def name(self):if not self.permission:raise PermissionError('不讓刪')del self.__name xiaobai=People('xiaobai',22,'male',1.80,67) print(xiaobai.name) xiaobai.name='xiaobai Lyn' print(xiaobai.__dict__) xiaobai.permission=True del xiaobai.name print(xiaobai.__dict__) 執行結果 xiaobai {'_People__name': 'xiaobai Lyn', '_People__age': 22, '_People__sex': 'male', '_People__height': 1.8, '_People__weight': 67, 'permission': False} {'_People__age': 22, '_People__sex': 'male', '_People__height': 1.8, '_People__weight': 67, 'permission': True} class Foo:def get_bar(self):return 'xiaobai'# *必須兩個參數def set_bar(self, value): return 'set value' + valuedef del_bar(self):return 'xiaobai'BAR = property(get_bar, set_bar, del_bar, 'description...')obj = Foo()obj.BAR # 自動調用第一個參數中定義的方法:get_bar obj.BAR = "youzi" # 自動調用第二個參數中定義的方法:set_bar方法,并將“youzi”當作參數傳入 del Foo.BAR # 自動調用第三個參數中定義的方法:del_bar方法 obj.BAE.__doc__ # 自動獲取第四個參數中設置的值:description...
?
轉載于:https://www.cnblogs.com/c491873412/p/7127244.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的python继承实现原理封装property的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ADVA收购Overture 扩张NFV
- 下一篇: 【BZOJ】2190 [SDOI2008