1. 程式人生 > >python之面向物件編制之封裝

python之面向物件編制之封裝

1.什麼是封裝

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

    裝:申請一個名稱空間,往裡裝入一系列名字/屬性

2.為什麼要封裝

    封裝資料屬性的目的

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

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

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

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

封裝函式屬性

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

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

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

精髓在於:隔離了複雜度

3.如何封裝

    如何隱藏:在屬性前面加上__開頭

    1.這種隱藏僅僅只是之中語法上的變形操作

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

   3.這種隱藏是對外不對內的,即在類的內部可以直接訪問,而在類的外側無法直接訪問

            原因是:

                在類定義階段,類的體內程式碼統一發生一次變形

    4.如果不想讓子類的方法覆蓋父類,可以將該方法前加一個__開頭

一.資料屬性發封裝

例:
# class People:				#隱藏僅僅只是一種語法上的變形操作
#     __country='China' 		#_People__country='China'
#     __n=100 					#_People__n=100
#     def __init__(self,name,age,sex):
#         self.__name=name 		#self._People__name=name
#         self.age=age
#         self.sex=sex
#
#     def eat(self):
#         print('eat.....')
#         print(People.__country) #People._People__country
#         print(self.__name) #self._People__name

# People.eat(123)
# print(People.__country)

# peo1=People('egon',18,'male')
# peo1.eat()
# print(peo1.__name)       	#外面不能呼叫,屬性的名字已經發生改變了

# print(People.__dict__)
# print(People.__country)
# print(People._People__country)

# People.__x=11
# print(People.__dict__)

例2:內部屬性全部隱藏,設定可以介面查詢,和修改的介面,設定操作許可權

class People:
    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 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                #外部不能直接修改。直接報錯
# peo1.age
# peo1.tell_info()

peo1.set_info('egon',19)		#設定一個開放介面,
# peo1.tell_info()

例2.封裝加繼承屬性的查詢

# 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()

二.函式屬性的封裝

property裝飾器用於將被裝飾的方法偽裝成一個數據屬性,在使用時可以不加括號而直接引用

class People:

    def __init__(self,name,weight,height):

        self.name=name

        self.weight=weight

        self.height=height

    @property

    def bmi(self):

            return self.weight / (self.height**2)

    peol=People('egon',75,1.8)

    print(peol.bmi)

class People:
    def __init__(self, name, weight, height):
        self.__name = name                      #資料熟悉隱藏+函式屬性隱藏
        self.__weight = weight
        self.__height = height
    @property
    def bmi(self):
        return self.__weight / (self.__height ** 2)

peol=People('egon',75,1.8)


print(peol.__dict__)
print(peol.bmi)

例,函式封裝之 檢視、修改、刪除,用法:

class People:
    def __init__(self,name):
        self.__name=name

    @property 					# 檢視obj.name
    def name(self):
        return '<名字是:%s>' %self.__name

    @name.setter 				#修改obj.name=值
    def name(self,name):
        if type(name) is not str:
            raise TypeError('名字必須是str型別傻叉')
        self.__name=name

    @name.deleter 				#刪除del obj.name
    def name(self):
        # raise PermissionError('不讓刪')       #raise是個異常報錯提示命令
        print('不讓刪除傻叉')
        # del self.__name

peo1=People('egon')
# print(peo1.name)

# print(peo1.name)		   #檢視

# peo1.name='EGON'                #修改
# print(peo1.name)

del peo1.name			  #刪除

2.函式封裝:簡潔使用方法

class People:
    def __init__(self,name):
        self.__name=name


    def tell_name(self):
        return '<名字是:%s>' %self.__name

    def set_name(self,name):
        if type(name) is not str:
            raise TypeError('名字必須是str型別傻叉')
        self.__name=name

    def del_name(self):
        print('不讓刪除傻叉')

    name=property(tell_name,set_name,del_name)     #python中簡潔使用方法


peo1=People('egon')

print(peo1.name)
peo1.name='EGON'
print(peo1.name)
del peo1.name