封裝:在程序設(shè)計(jì)中担平,封裝(Encapsulation)是對具體對象的一種抽象李剖,即將某些部分隱藏起來芒率,在程序外部看不到,其含義是其他程序無法調(diào)用篙顺。要了解封裝敲董,離不開“私有化”,就是將類或者是函數(shù)中的某些屬性限制在某個區(qū)域之內(nèi)慰安,外部無法調(diào)用。
1聪铺、在封裝的基礎(chǔ)上化焕,我可以將裝到對象或者類中的屬性給隱藏起來
注意:
(1)在定義類或者初始化對象時(shí),在屬性前加__,就會將該屬性隱藏起來
但該隱藏其實(shí)只是pycharm把這個變量名變?yōu)榱硪粋€命名方式铃剔,并沒有真的隱藏起來撒桨,如
# 原本定義
self.name = name
# 隱藏起來
self.__name = name
'''
一種變形_類名__屬性名,其實(shí)是把他變成_類名__屬性名
'''
(2)該變形操作是在類定義階段掃描語法時(shí)發(fā)生的變形键兜,類定義之后添加的__開頭的屬性不會發(fā)生變形
(3)該隱藏是對外不對內(nèi)
(4)在繼承中凤类,父類如果不想讓子類覆蓋自己的方法,可以將方法定義為私有的
class Student:
__school = "oldboy" # _Student__school = "oldboy"
def __init__(obj, x, y, z):
obj.__name = x # obj._Student__name = x
obj.age = y
obj.gender = z
def __choose(self): # obj._Student__choose
print("%s 正在選課" %self.name)
stu_obj1 = Student("馮瘋子", 18, "female")
stu_obj1.__x=111
print(stu_obj1.__dict__)
print(stu_obj1.__x)
print(stu_obj1.__dict__)
print(stu_obj1._Student__name)
print(Student.__dict__)
print(Student._Student__school)
print(stu_obj1._Student__school)
隱藏屬性的意義何在
1普气、把數(shù)據(jù)屬性隱藏起來的意義是:我們可以使用接口(其實(shí)就是函數(shù))谜疤,把我們想讓使用者使用的功能加以限制,比如我們可以先在函數(shù)里經(jīng)過一系列的邏輯運(yùn)算,來控制外界使用者對屬性的操作夷磕。
以下例子履肃,為實(shí)現(xiàn)對輸入年齡的類型做控制,正在原來的方法中坐桩,age沒辦法控制輸入的類型尺棋,可以是int,也可以是str绵跷,如age='haavavlvl'
class Student:
__school = "oldboy" # _Student__school = "oldboy"
def __init__(obj, x, y, z):
obj.__name = x # obj._Student__name = x
obj.__age = y
obj.gender = z
def __choose(self): # obj._Student__choose
print("%s 正在選課" % self.name)
def get_name(self):
print(self.__name) # print(self._Student__name)
def set_age(self,x):
if type(x) is not int:
print("年齡必須是整型")
return
self.__age = x
def get_age(self):
print(self.__age)
def del_age(self):
del self.__age
stu_obj1 = Student("馮瘋子", 18, "female")
# stu_obj1.get_name()
# stu_obj1.set_age("asfdasfdasfafd")
stu_obj1.set_age(19)
stu_obj1.get_age()
# print(stu_obj1.__dict__)
2膘螟、把功能屬性隱藏起來:隔離復(fù)雜度
class ATM:
def __card(self):
print('插卡')
def __auth(self):
print('用戶認(rèn)證')
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()
至此,我們就通過封裝的隱藏屬性與提供接口實(shí)現(xiàn)了創(chuàng)建對象時(shí)屬性的控制
2.property(特性)
property是一個特殊的屬性碾局,訪問它時(shí)會執(zhí)行一段功能(函數(shù))荆残,他是一個裝飾器
例1計(jì)算bmi指數(shù)
class People:
def __init__(self, name, height, weight):
self.name = name
self.height = height
self.weight = weight
@property
def bmi(self):
return self.weight / (self.height ** 2)
p = People('egon', 1.81, 70)
p.height = 1.84
# 不加裝飾器property時(shí)
print(p.bmi())
# 加裝飾器時(shí)候
print(p.bmi)
例2:property的老式用法
class Student:
__school = "oldboy" # _Student__school = "oldboy"
def __init__(obj, x, y, z):
obj.__name = x
obj.__age = y
obj.gender = z
def get_name(self):
print("訪問控制")
return self.__name
def set_name(self,x):
print("賦值控制")
self.__name = x
def del_name(self):
print("刪除控制")
del self.__name
def get_age(self):
return self.__age
def set_age(self, x):
if type(x) is not int:
print("年齡必須是整型,傻叉")
return
self.__age = x
def del_age(self):
print("不讓刪")
age = property(get_age, set_age, del_age)
name = property(get_name, set_name, del_name)
stu_obj1 = Student("馮瘋子", 18, "female")
# print(stu_obj1.age)
# stu_obj1.age = "19"
# del stu_obj1.age
# print(stu_obj1.age)
print(stu_obj1.name)
# stu_obj1.name="EGON"
# del stu_obj1.name
例3:property的新式用法
class Student:
__school = "oldboy" # _Student__school = "oldboy"
def __init__(obj, x, y, z):
obj.__name = x
obj.__age = y
obj.gender = z
@property
def name(self):
print("訪問控制")
return self.__name
@name.setter
def name(self, x):
print("賦值控制")
self.__name = x
@name.deleter
def name(self):
print("刪除控制")
del self.__name
stu_obj1 = Student("馮瘋子", 18, "female")
stu_obj1.name
3.類方法(classmethod)與靜態(tài)方法(staticmethod)
綁定方法:
1擦俐、類中定義的函數(shù)默認(rèn)就是綁定給對象的方法脊阴,應(yīng)該由對象調(diào)用,會把對象當(dāng)做第一個參數(shù)
2蚯瞧、若使用classmethod裝飾器嘿期,就會把函數(shù)綁定給類,pycharm會自動幫你傳一個形參埋合,cls备徐,表示該函數(shù)綁定給類,應(yīng)該由類來調(diào)用甚颂,會把類當(dāng)做第一個參數(shù)
@classmethod
def f1(cls):
print(cls)
3蜜猾、若使用靜態(tài)方法static裝飾器,表示不與類綁定也不與對象綁定振诬,就是普通函數(shù)蹭睡,需要什么參數(shù)就傳什么參數(shù)
@staticmethod
def f2(x,y,z):
print(x,y,z)