物件導向之封裝之如何隱藏屬性, 封裝的底層原理

2022-09-17 07:48:12 字數 3771 閱讀 3703

1.什麼是封裝:?

封:屬性對外是隱藏的,但對內是開放的。

裝:申請乙個命名空間,往裡裝入一系列名字/屬性。(類和物件都是有乙個命名空間,往裡面裝一系列的名字)

2、為什麼要封裝

封裝資料屬性的目的

首先定義屬性的目的就是為了給類外部的使用使用的,

隱藏之後是為了不讓外部使用直接使用,需要類內部開闢乙個介面

然後讓類外部的使用通過介面來間接地操作隱藏的屬性。

精髓在於:我們可以在介面之上附加任意邏輯,從而嚴格控制使用者對屬性的操作

封裝函式屬性

首先定義屬性的目的就是為了給類外部的使用使用的,

隱藏函式屬性是為了不讓外不直接使用,需要類內部開闢乙個介面

然後在介面內去呼叫隱藏的功能

精髓在於:隔離了複雜度

3、如何封裝

注意:如何隱藏?

再屬性前面加__開頭

重點:這種隱藏式對外不對內的,即再類的內部可以直接訪問,而在類的外部則無法直接訪問。原因是在類定義階段,類體內**

統一發生了一次變形。

下面是證明上面一行話的例子:

一種情況:

再類的裡面隱藏資料屬性,類再內部可以訪問到這個隱藏的屬性,類再類的外部就訪問不到這個隱藏的屬性了

class people:

__county='china' #再想隱藏的屬性前面加__開頭

def __init__(self,name,age,***):

self.name=name

self.age=age

self.***=***

def eat(self):

print('eat...')

print(people.__county) #再類的內部呼叫改變過的屬性。通過類名呼叫屬性。

peo1=people('egon',18,'male')

# people.eat(111) #呼叫函式後,print(people.__county)能訪問到,說明對內能訪問到

print(people.__county) #再外部直接訪問改變後的屬性,會報錯

二種情況:

# 再類的裡面隱藏資料屬性或者函式屬性,物件再內部可以訪問到隱藏的屬性,物件再類的外部就訪問不到隱藏的屬性。

# class people:

# __county='china' #再想隱藏的屬性前面加__開頭

# def __init__(self,name,age,***):

# self.__name=name #隱藏屬性名

# self.age=age

# self.***=***

# def eat(self):

# print('eat...')

# print(self.__name) #物件在類內部呼叫隱藏的屬性

# peo1=people('egon',18,'male')

# peo1.eat() #驗證物件在類內部可以訪問到隱藏的屬性。

# print(peo1.__name) #驗證物件在類外部訪問不到隱藏的屬性。

封裝的底層原理

2.這種語法上的變形只在定義階段發生一次,因為類體**僅僅只在類定義階段檢查一次

例如:

# 只要是__開頭的屬性,它在往命名空間裡面丟的時候,都做了乙個變形。成了_類名__屬性名

class people:

__county='china' #_people__county

__n=100

def __init__(self,name,age,***):

self.__name=name #

self.age=age

self.***=***

def eat(self):

print('eat...')

# print(people.__county)

print(self.__county)

s1=people('egon',18,'male')

s1.eat()

# print(people.__dict__) #檢視people裡面的隱藏屬性都做了變形,成了_people__county

print(people._people__county) #直接訪問這個變了形的屬性名,可以直接訪問到

people.__x=1    #再這裡__x不會變形,因為這個變形只在類定義階段發生一次,定義階段變形後,其他再操作__開頭都沒用了

print(people.__dict__)

# 總結:這種隱藏僅僅是一種語法上的變形操作。

為什麼在內部可以訪問到被隱藏的屬性?

因為類再定義階段就會執行類體**,執行之前會先檢測語法,這個檢測只在類定義階段發生一次

再內部能訪問到,是因為內部的訪問再當初檢測語法的時候,都一塊變形了。都變成了

最真實的形式

例項訓練:

class foo:

def __f1(self): #_foo__f1

print('foo.f1')

def f2(self):

print('foo.f2')

self.__f1() #self._foo__f1()

class bar(foo):

def __f1(self): #_bar__f1

print('bar.f1')

obj=bar()

obj.f2()

結果是:

foo.f2

foo.f1

總結:如果不想讓子類的方法覆蓋父類的,可以該方法名前加乙個__開頭。

用隱藏屬性這個方法,是如何用呢?

封裝資料屬性的目的

首先定義屬性的目的就是為了給類外部的使用使用的,

隱藏之後是為了不讓外部使用直接使用,需要類內部開闢乙個介面

然後讓類外部的使用通過介面來間接地操作隱藏的屬性。

精髓在於:我們可以在介面之上附加任意邏輯,從而嚴格控制使用者對屬性的操作

# 想嚴格控制屬性的型別。要做兩步:

# 一步是:隱藏屬性,外部看不到,想看設計者可以在內部開乙個介面,

# 直接用這個介面,再介面內附加一些控制的邏輯

def set_info(self,name,age): #開乙個介面,可以改裡面的屬性。

if type(name) is not str:

# print('使用者名稱必須為str型別')

# return

raise typeerror('使用者名稱必須為str型別')

if type(age) is not int:

# print('年齡必須為int型別')

# return

raise typeerror('年齡必須為int型別')

self.__name=name

self.__age=age

peo1=people('egon',18)

# peo1.name=123 #再原來沒有隱藏屬性的時候,型別可以隨便用,沒限制,123也沒關係

# peo1.age

# peo1.tell_info()

peo1.set_info('egon',19)

# peo1.tell_info()

物件導向之封裝

定義 影藏事物的屬性和實現的細節,僅對外提供公共的訪問方式 封裝的好處 1.隱藏了事物的細節 2.提高了 的復用性 3.提高了安全性 封裝的實現 使用private關鍵字進行修飾,被private修飾的成員只能在本類中使用 setter和getter 封裝需要搭配set和get方法 set 設定器 ...

物件導向之封裝

封裝之如何隱藏屬性 在變數名和方法名之前加雙下劃線 外部就訪問不到 classa x 1def init self,name self.name name def bar self print self.name a.x 外部無法訪問這其實是在類定義的時候,將變數名和函式名進行了變形,我們可以列印類...

物件導向之 封裝

封裝 就是把屬性或者方法裝起來 廣義 把屬性和方法裝起來,外面不能直接呼叫了,要通過類的名字來呼叫 狹義 把屬性和方法藏起來,外面不能呼叫,只能在內部偷偷呼叫 class user def init self,name,passwd self.usr name self.pwd passwd 私有的...