中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

面向對象-封裝

發布時間:2020-06-21 13:33:06 來源:網絡 閱讀:304 作者:DevOperater 欄目:編程語言

1.設置私有變量和函數

1.1變量和函數的隱藏

python中用雙下劃線開頭的方式把屬性隱藏起來(設置成私有的)

#!/usr/bin/env python
# -*- coding:utf-8 -*-
# Author: vita
#其實這僅僅這是一種變形操作
#類中所有雙下劃線開頭的名稱如__x都會自動變形成:_類名__x的形式:

class A:
    __N=0 #類的數據屬性就應該是共享的,但是語法上是可以把類的數據屬性設置成私有的如__N,會變形為_A__N
    def __init__(self):
        self.__X=10 #類定義時就變形為self._A__X
    def __foo(self): #類定義時就變形為_A__foo
        print('from A')
    def bar(self):
        self.__foo() #只有在類內部才可以通過__foo的形式訪問到.
a = A()
print("a.__dict__",a.__dict__)
#定義后的賦值操作,不會變形為_類名__N
a.__Y=1
print("a.__dict__",a.__dict__)
print("a._A__N:",a._A__N)
print("A._A__N:",A._A__N)
#A._A__N是可以訪問到的,即這種操作并不是嚴格意義上的限制外部訪問,僅僅只是一種語法意義上的變形

E:\PythonProject\python-test\venvP3\Scripts\python.exe E:/PythonProject/python-test/BasicGrammer/test.py
a.__dict__ {'_A__X': 10}
a.__dict__ {'_A__X': 10, '__Y': 1}
a._A__N: 0
A._A__N: 0

Process finished with exit code 0
這種自動變形的特點:
1.類中定義的__x只能在內部使用,如self.__x,引用的就是變形的效果。
2.這種變形其實是針對外部的變形,在外部是無法通過__x這個名字訪問到的。
3.在子類定義的__x不會覆蓋在父類定義的__x,
因為子類中變形成了:_子類名__x,
而父類中變形成了:_父類名__x,即雙下劃線開頭的屬性在繼承給子類時,子類時無法覆蓋的。
這種變形要注意的問題:
"1.這種機制并沒有真正意義上限制我們從外部直接訪問屬性,知道了類名和屬性名還可以拼出名字:_類名__屬性,然后就可以訪問了,如a._A__N或A._A__N"
"2.變形的過程只在類定義時發生一次,在定義后的賦值操作,不會發生變形"
print("a.__dict__",a.__dict__)
#定義后的賦值操作,不會變形為_類名__N
a.__Y=1
print("a.__dict__",a.__dict__)

a.__dict__ {'_A__X': 10}
a.__dict__ {'_A__X': 10, '__Y': 1}#這里依舊是__Y,并沒變形為_A__Y
"3.在繼承中,父類如果不想讓子類覆蓋自己的方法,可以把方法定義為私有的"

#正常情況
>>> class A:
...     def fa(self):
...         print('from A')
...     def test(self):
...         self.fa()  #這里先到對象自身的類中找,找不到再到A類中找
... 
>>> class B(A):
...     def fa(self):
...         print('from B')
... 
>>> b=B()
>>> b.test()
from B

#把fa定義成私有的,即__fa
>>> class A:
...     def __fa(self): #在定義時就變形為_A__fa
...         print('from A')
...     def test(self):
...         self.__fa() #在定義階段,變形為self._A__fa,所以只會與自己所在的類為準
... 
>>> class B(A):
...     def __fa(self): #在定義階段,變形為self._B__fa
...         print('from B')
... 
>>> b=B()
>>> b.test() #注意這里調用的self.__fa()為類A中的__fa()
from A

1.2封裝不是單純意義的隱藏

1.2.1封裝數據

將數據隱藏起來不是目的。隱藏起來然后對外提供操作數據的接口,然后就可以在接口附加上對該數據操作的限制,以此完成對數據屬性操作的嚴格限制

class Teacher:
    def __init__(self,name,age):
        self.__name=name
        self.__age=age

    def tell_info(self):
        print('姓名:%s,年齡:%s' %(self.__name,self.__age))
    def set_info(self,name,age):
        if not isinstance(name,str):
            raise TypeError('姓名必須是字符串類型')
        if not isinstance(age,int):
            raise TypeError('年齡必須是整型')
        self.__name=name
        self.__age=age

t=Teacher('egon',18)
t.tell_info()

t.set_info('egon',19)
t.tell_info()

1.2.2封裝方法

目的是隔離復雜度

#取款是功能,而這個功能有很多功能組成:插卡、密碼認證、輸入金額、打印賬單、取錢
#對使用者來說,只需要知道取款這個功能即可,其余功能我們都可以隱藏起來,很明顯這么做
#隔離了復雜度,同時也提升了安全性

class ATM:
    def __card(self):
        print('插卡')
    def __auth(self):
        print('用戶認證')
    def __input(self):
        print('輸入取款金額')
    def __print_bill(self):
        print('打印賬單')
    def __take_money(self):
        print('取款')

    def withdraw(self):
        self.__card()
        self.__auth()
        self.__input()
        self.__print_bill()
        self.__take_money()

a=ATM()
a.withdraw()

1.3封裝與擴展性

封裝在于明確區分內外,使得類實現者可以修改封裝內的東西而不影響外部調用者的代碼。
外部調用者只需要知道函數名,只要函數名,參數不變,使用者的代碼就不需要改變。這就提供了一個良好的合作基礎。

#類的設計者
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #對外提供的接口,隱藏了內部的實現細節,此時我們想求的是面積
        return self.__width * self.__length

#使用者
>>> r1=Room('臥室','egon',20,20,20)
>>> r1.tell_area() #使用者調用接口tell_area

#類的設計者,輕松的擴展了功能,而類的使用者完全不需要改變自己的代碼
class Room:
    def __init__(self,name,owner,width,length,high):
        self.name=name
        self.owner=owner
        self.__width=width
        self.__length=length
        self.__high=high
    def tell_area(self): #對外提供的接口,隱藏內部實現,此時我們想求的是體積,內部邏輯變了,只需求修該下列一行就可以很簡答的實現,而且外部調用感知不到,仍然使用該方法,但是功能已經變了
        return self.__width * self.__length * self.__high

#對于仍然在使用tell_area接口的人來說,根本無需改動自己的代碼,就可以用上新功能
>>> r1.tell_area()
向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

仪征市| 翁源县| 丹江口市| 洪泽县| 利川市| 南溪县| 丹巴县| 都江堰市| 陆河县| 东莞市| 磐石市| 马边| 仁布县| 扬州市| 瓮安县| 延吉市| 汤原县| 县级市| 文水县| 邵阳市| 清涧县| 山阴县| 蚌埠市| 潼南县| 道孚县| 噶尔县| 青铜峡市| 五大连池市| 屯门区| 马鞍山市| 东山县| 会同县| 利津县| 太仆寺旗| 泗洪县| 汾西县| 龙胜| 比如县| 恩施市| 宝坻区| 普定县|