===私有化===
1.屬性和方法的訪問(wèn)權(quán)限
??私有的:在類的外部不可以使用,也不可以繼承
??保護(hù)的:在類的外部不可以使用,可以繼承
??公開(kāi)的:在類的外部可以使用必盖,也可以被繼承
2.python的私有化
??python中屬性和方法的訪問(wèn)權(quán)限只有公開(kāi)隧出,但是提供了另一種私有化的方式。
??python中在屬性或者方法名前加__剔宪,就可以將屬性或者方法變成私有的(注意:只能兩__開(kāi)頭,不能__結(jié)尾)
??私有的屬性和方法只能在類的內(nèi)部使用壹无,不能在類的外面使用
class Person:
__num2 = 62 # 私有化變量
def __run(self): # 私有化方法
print('%s在跑步' % self.name)
3.python私有化的原理
??在名字前是__的屬性和方法前再加'_類名'去保存屬性和方法
class Person:
__num2 = 62
print(__num2) # 不能打印num2
print(_Person.__num2) # 可以打印num2
===getter和setter(了解)===
1.應(yīng)用場(chǎng)景
??getter: 獲取對(duì)象屬性的值之前想要做點(diǎn)兒別的事情葱绒,就給這個(gè)屬性添加getter
??setter: 給對(duì)象屬性賦值之前想要做點(diǎn)兒別的事情,就給這個(gè)屬性添加setter
2.getter
??第一步:聲明屬性的時(shí)候在屬性名前加_
??第二步: 聲明函數(shù)(函數(shù)沒(méi)有除了self以外的參數(shù)斗锭,但是要與返回值地淀。返回值就是獲取屬性拿到的值)
??@property
??def 去掉的屬性名(self):
????做點(diǎn)別的事情
????返回屬性的值
??第三步:在類的外部通過(guò)對(duì)象.去掉的屬性去獲取相關(guān)的屬性
class Person:
def __init__(self, name=''):
self.name = name
self._age = 0
self._week = 7 # 屬性名前有_,使用屬性的時(shí)候不要直接用
@property
def age(self):
return self._age
# 給age添加setter
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError
if not (0 <= value <= 150):
raise ValueError
self._age = value
3.setter - 想要添加setter必須先要有g(shù)etter
??第一步:聲明屬性的時(shí)候在屬性名前加_
??第二步: 聲明函數(shù)(函數(shù)除了self以外還需要一個(gè)參數(shù)岖是,沒(méi)有返回值帮毁。這兒的參數(shù)代表給屬性賦的值)
??@屬性名去掉.setter
??def 去掉的屬性名(self, 參數(shù)):
????做點(diǎn)別的事情
????給屬性賦值
??第三步:在類的外部通過(guò)對(duì)象.去掉_的屬性去給相關(guān)屬性賦值
class Person:
def __init__(self, name=''):
self.name = name
self._age = 0
self._week = 7 # 屬性名前有_,使用屬性的時(shí)候不要直接用
# 給week添加getter
@property
def week(self):
if self._week < 7:
return '星期%d' % self._week
else:
return '星期天'
===繼承===
1.什么是繼承
??一個(gè)類繼承另外一個(gè)類豺撑,其中會(huì)產(chǎn)生繼承者和被繼承者烈疚。這兒的繼承者叫子類,被繼承者叫父類/超類
??繼承就是讓子類直接擁有父類的方法和屬性
2.怎么繼承
語(yǔ)法:
??class 類名(父類列表):
??類的內(nèi)容
說(shuō)明:
??a.python中所有的類都是直接或者間接繼承自基類object
????class 類名: ===> class 類名(object):
??b.python中的繼承支持多繼承聪轿, 父類列表中可以有多個(gè)類爷肝,多個(gè)類之間用逗號(hào)隔開(kāi)
3.能繼承哪些東西: 所有的屬性和方法都能夠繼承
注意:
??a.slots的值繼承后沒(méi)有效果
??b.在類中給slots賦值后,當(dāng)前類的對(duì)象不能使用dict;但是這個(gè)類的子類對(duì)象可以使用dict,只是dict中沒(méi)有從父類繼承下來(lái)的對(duì)象屬性屹电,只有在子類中添加的對(duì)象屬性
??c.如果父類沒(méi)有給slots賦值阶剑,直接給子類的slots,無(wú)效危号!
===添加方法===
1.添加方法
??直接在子類中聲明新的方法
class Person(object):
num = 61
def __init__(self,name='zhangsan', age=0, sex='男'):
self.name = name
self.age = age
self.sex = sex
self.__face = 60
def eat(self, food):
print('%s在吃%s' % (self.name, food))
@classmethod
def show_num(cls):
print('人類的數(shù)量:%d' % cls.num)
class Student(Person):
num2 = 100
# 添加方法
def study(self):
print('%s在寫(xiě)代碼' % self.name)
2.重寫(xiě)方法
??在子類中重新實(shí)現(xiàn)父類的方法 - 完全重寫(xiě)
??保留父類的功能在子類中添加新的功能 - 部分重寫(xiě)(在子類方法中通過(guò)'super().'的方式調(diào)用父類方法)
@classmethod
def show_num(cls):
print('學(xué)生數(shù)量:%d' % cls.num)
3.類中函數(shù)的調(diào)用過(guò)程
??回到函數(shù)聲明的位置:先看當(dāng)前類中是否有方法牧愁,如果有就直接調(diào)用當(dāng)前類中的方法;沒(méi)有就去看父類中有沒(méi)有這個(gè)方法外莲;如果父類中也沒(méi)有就看父類的父類中有沒(méi)有....直到找到object類猪半,如果object中也沒(méi)有就報(bào)錯(cuò)兔朦!
def eat(self, food):
super().eat(food)
print('吃飽了')
===添加屬性===
1.類的字段
??直接在子類中聲明新的字段
class Person(object):
num = 61
class Student(Person):
num2 = 100
2.添加對(duì)象屬性
??對(duì)象屬性其實(shí)是通過(guò)繼承init方法繼承下來(lái)的
class Animal:
def __init__(self, age):
self.age = age
self.color = '灰色'
class Dog(Animal):
def __init__(self, name, age):
# 調(diào)用父類的init方法來(lái)繼承父類的對(duì)象屬性
super().__init__(age)
self.name = name
class Cat(Animal):
pass
===運(yùn)算符重載===
1.什么是運(yùn)算符重載
??通過(guò)實(shí)現(xiàn)類中相應(yīng)的魔法方法來(lái)讓當(dāng)前類的對(duì)象支持相應(yīng)的運(yùn)算符
??注意:python中所有的數(shù)據(jù)類型都是類; 所有的數(shù)據(jù)都是對(duì)象
class Student(object):
def __init__(self, name='', age=0, score=0):
self.name = name
self.age = age
self.score = score
def __repr__(self):
return '<' + str(self.__dict__)[1:-1] + '>'
# 實(shí)現(xiàn)'+'對(duì)應(yīng)的魔法方法,讓兩個(gè)學(xué)生對(duì)象能夠進(jìn)行+操作
# self和other的關(guān)系: self+other ==> self.__add__(other)
# 返回值就是運(yùn)算結(jié)果
def __add__(self, other):
# a.支持Student+Student:
return self.age + other.age
# b.支持Student+數(shù)字
# return self.age + other
# self * other
# 將other當(dāng)成數(shù)字
def __mul__(self, other):
return self.name * other
# self和other都是學(xué)生對(duì)象
# 注意:大于和小于運(yùn)算符是需要重載一個(gè)就行
def __gt__(self, other):
return self.score > other.score
===內(nèi)存管理===
1.數(shù)據(jù)的存儲(chǔ)
??內(nèi)存分為棧區(qū)間和堆區(qū)間磨确;從底層來(lái)看沽甥,棧區(qū)間的內(nèi)存的開(kāi)辟和釋放是系統(tǒng)自動(dòng)管理的,堆區(qū)間的內(nèi)存是由程序員通過(guò)代碼開(kāi)辟(malloc)和釋放的
??從python語(yǔ)言角度乏奥,棧區(qū)間的內(nèi)存的開(kāi)辟和釋放是系統(tǒng)自動(dòng)管理的摆舟,堆區(qū)間的內(nèi)存關(guān)鍵也已經(jīng)封裝好了,程序員也不需要寫(xiě)代碼來(lái)開(kāi)辟空間和釋放空間
??a.python中變量本身是存在棧區(qū)間的,函數(shù)調(diào)用過(guò)程是在棧區(qū)間; 對(duì)象都是存在堆區(qū)間(python中所有數(shù)據(jù)都是對(duì)象)
??b.變量賦值過(guò)程:先堆區(qū)間開(kāi)辟空間將數(shù)據(jù)存起來(lái)邓了, 然將數(shù)據(jù)對(duì)應(yīng)的地址存到棧區(qū)間的變量中恨诱。
??數(shù)字和字符串比較特殊,賦值的時(shí)候不會(huì)直接開(kāi)辟空間骗炉,而是先檢測(cè)之前有沒(méi)有存儲(chǔ)過(guò)這個(gè)數(shù)據(jù)照宝,如果有就用之前的數(shù)據(jù)的地址
2.內(nèi)存釋放(垃圾回收機(jī)制)原理:
??python中的每個(gè)對(duì)象都有一個(gè)屬性叫'引用計(jì)數(shù)',表示當(dāng)前對(duì)象的引用的個(gè)數(shù)。判斷一個(gè)對(duì)象是否銷毀就看對(duì)象的引用計(jì)數(shù)是否為0句葵;
為0的就銷毀厕鹃,不為0的就不銷毀。
??getrefcount函數(shù):
??getrefcount(對(duì)象) -> 獲取對(duì)象的引用計(jì)數(shù)
list1 = [1, 2]
print(getrefcount(list1)) # 2
# 使用不同的變量存對(duì)象地址會(huì)增加引用計(jì)數(shù)
list2 = list1
print(getrefcount(list1)) # 3
[1, list1]
print(getrefcount(list1)) # 3