1.訪問(wèn)權(quán)限
私有的:在類(lèi)的外部不可以使用,也不可以繼承
保護(hù)的:在類(lèi)的外部不可以使用,可以繼承
公開(kāi)的:在類(lèi)的外部可以使用,也可以被繼承
2.Python中屬性和方法的訪問(wèn)權(quán)限只有公開(kāi),但是提供了另一種私有化的方式。
3.Python中在屬性或者方法名前加,就可以降屬性或者方法私有化,只能兩個(gè)下劃線開(kāi)頭,不能結(jié)尾
私有的屬性和方法只能在類(lèi)的內(nèi)部使用,不能在類(lèi)的外面使用
4.Python私有化的原理
在名字前是的屬性和方法在家'_類(lèi)名'去保存屬性和方法
class Person:
num =31
def __init__(self,name,age):
self.name = name
self.age = age
def eat(self,food):
print('%s吃%s'%(self.name,food))
@classmethod
def show_num(cls):
print('人類(lèi)的數(shù)量:%d'%cls.num)
@staticmethod
def func1():
print('wqwqwqqwqwqwqwqwqwqwqw')
def main():
p1 = Person('曾令鵬',18)
1.應(yīng)用場(chǎng)景
getter:獲取對(duì)象屬性的值之前想要做點(diǎn)別的事情,就給這個(gè)屬性添加getter
setter:給對(duì)象屬性賦值之前想要做點(diǎn)別的事情,就給這個(gè)屬性添加setter
2.getter
第一步:聲明屬性的時(shí)候在屬性名前加_
第二步:聲明一個(gè)函數(shù)(函數(shù)沒(méi)有除了self以外的參數(shù),要是要有返回值。返回值就是獲取屬性拿到的值)
@property
def 去掉的屬性名(self):
做點(diǎn)別的事情
返回屬性的值
第三步:在類(lèi)的外部通過(guò)對(duì)象.去掉的屬性去獲取相關(guān)的屬性
3.setter --想要添加setter必須先有g(shù)etter
第一步:聲明屬性的時(shí)候在屬性名前加_
第二步:聲明函數(shù)(函數(shù)除了self以外還需要一個(gè)參數(shù),沒(méi)有返回值。這兒的參數(shù)代表給屬性賦的值)
@屬性名去掉.setter
def 去掉的屬性名(self,參數(shù)):
做點(diǎn)別的事情
給屬性賦值
第三步:在類(lèi)的外部通過(guò)對(duì)象.去掉的屬性去給相關(guān)屬性賦值
注意:通過(guò)不帶的屬性給屬性賦值實(shí)質(zhì)是在調(diào)用setter對(duì)應(yīng)的函數(shù)
通過(guò)不帶_的水性來(lái)獲取屬性的值實(shí)質(zhì)是在調(diào)用getter對(duì)應(yīng)的函數(shù)
class Person:
def __init__(self, name=''):
self.name = name
self._age = 0
self._week = 1
# 添加getter
@property
def week(self):
if self._week < 7:
return '星期%d' % self._week
elif self._week:
return '星期天'
@property
def age(self):
return self._age
@age.setter
def age(self, value):
if not isinstance(value, int):
raise ValueError
if not (0 <= value <= 150):
raise ValueError
self._age = value
def main():
p1 = Person
p1.age = 233
print(p1.age)
1.一個(gè)類(lèi)繼承另外一個(gè)類(lèi),其中會(huì)產(chǎn)生產(chǎn)生繼承者和被繼承者。這兒的繼承者叫子類(lèi),被繼承者叫父類(lèi)或者超類(lèi)
繼承就是讓子類(lèi)直接擁有父類(lèi)的方法和屬性
2.怎么繼承
a.語(yǔ)法:
class 類(lèi)名(父類(lèi)):
類(lèi)的內(nèi)容
說(shuō)明:
a.Python中所有的類(lèi)都是直接或者間接繼承自object(基類(lèi))
b.Python中的繼承支持多繼承,父類(lèi)列表可以有多個(gè)類(lèi),多個(gè)類(lèi)之間用逗號(hào)隔開(kāi)
**注意:a.slots的值繼承后沒(méi)有效果
b.在類(lèi)中給slots_賦值后,當(dāng)前類(lèi)的對(duì)象不能使用dict;但是這個(gè)類(lèi)的子類(lèi)對(duì)象可以使用dict
只是dict中沒(méi)有從父類(lèi)繼承下來(lái)的屬性,只有在子類(lèi)中添加的對(duì)象屬性
c.如果父類(lèi)沒(méi)有給slots賦值,直接給子類(lèi)的slots,無(wú)效
多繼承:多繼承的時(shí)候,多個(gè)父類(lèi)中的所有方法都可以繼承,只是對(duì)象屬性只能繼承第一個(gè)父類(lèi)的
class Person(object):
num =52
def __init__(self,name='',age=0,sex='男'):
self.name = name
self.age = age
self.sex=sex
def eat(self,food):
print('%s在吃%s'%(self.name,food))
@classmethod
def show_num(cls):
print(cls.num)
class Student(Person):
pass
def main():
s1 =Student
print(s1.__dict__)
==========================添加方法==============================
1.添加方法
直接在子類(lèi)中聲明新的方法
子類(lèi)可以使用父類(lèi)的屬性和方法,但是父類(lèi)不能使用子類(lèi)中添加的方法
2.重寫(xiě)方法
在子類(lèi)中重新實(shí)現(xiàn)父類(lèi)的方法 --完全重寫(xiě)
保留父類(lèi)的功能在子類(lèi)中添加新的功能 -部分重寫(xiě)(在子類(lèi)方法中通過(guò)super().的方式調(diào)用父類(lèi)方法
3.類(lèi)中函數(shù)的調(diào)用過(guò)程
回到函數(shù)聲明的位置:先看當(dāng)前類(lèi)中是否有方法,如果有就直接調(diào)用當(dāng)前類(lèi)中的方法,
如果有就調(diào)用,沒(méi)有就看父類(lèi)中是否有,如果父類(lèi)中也沒(méi)有就看父類(lèi)的父類(lèi)
直到找到object類(lèi),還是沒(méi)有就報(bào)錯(cuò)
=============================添加屬性===========================
1.類(lèi)的字段
直接在子類(lèi)聲明新的字段
class Person(object):
num =52
def __init__(self,name='',age=0,sex='男'):
self.name = name
self.age = age
self.sex=sex
def eat(self,food):
print('%s在吃%s'%(self.name,food))
@classmethod
def show_num(cls):
print(cls.num)
class Student(Person):
def study(self):
print('%s在寫(xiě)代碼'%self.name)
def eat(self):
super
@classmethod
def show_num(cls): #完全重寫(xiě)
print('xuesheng%s'%cls.num)
def main():
s1 = Student('曾令鵬')
s1.study()
添加對(duì)象屬性:
對(duì)象屬性其實(shí)是通過(guò)繼承init方法繼承下來(lái)的
class Animal:
def __init__(self):
self.age = 0
self.color = '灰色'
class Dog():
def __init__(self, name):
# 調(diào)用父類(lèi)的init方法來(lái)繼承父類(lèi)的對(duì)象屬性
super().__init__()
self.name = name
def main():
pass
1.運(yùn)算符重載
通過(guò)實(shí)現(xiàn)類(lèi)中相應(yīng)的魔法方法來(lái)讓當(dāng)前類(lèi)的對(duì)象支持相應(yīng)的運(yùn)算符
class Student():
def __init__(self,name,age,score):
self.name = name
self.age = age
self.score = score
實(shí)現(xiàn)'+'對(duì)應(yīng)的魔法方法,讓兩個(gè)學(xué)生對(duì)象能夠進(jìn)行+操作
self和other的關(guān)系:self+other
def __add__(self, other):
return self.age + other.age
def main():
stu1 =Student('小明',18,97)
stu2 = Student('小花',19,87)
print(stu1+stu2) #print(stu1.__add__(stu2))
if __name__ == '__main__':
main()
內(nèi)存管理
1.數(shù)據(jù)的存儲(chǔ)
內(nèi)存分為棧區(qū)間和堆區(qū)間:從底層看棧區(qū)間的內(nèi)存開(kāi)辟和釋放是系統(tǒng)自動(dòng)管理的,堆區(qū)間是由程序員通過(guò)代碼開(kāi)辟和釋放的
從Python語(yǔ)言角度,堆區(qū)間的內(nèi)存開(kāi)辟和釋放是系統(tǒng)自動(dòng)管理的,堆區(qū)間的內(nèi)存關(guān)鍵也已經(jīng)封裝好了
a.Python中變量本身是存在棧區(qū)間的,函數(shù)調(diào)用過(guò)程是在棧區(qū)間;對(duì)象都是存在堆區(qū)間(Python中所有的數(shù)據(jù)都是對(duì)象)
b.Python中變量賦值過(guò)程:現(xiàn)在堆區(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ù),如果有就用這個(gè)地址,沒(méi)有就開(kāi)辟
2.內(nèi)存釋放(垃圾回收機(jī)制)原理:
Python中的每個(gè)對(duì)象都有一個(gè)屬性叫引用計(jì)數(shù),表示當(dāng)前對(duì)象的引用個(gè)數(shù)。判斷一個(gè)對(duì)象是否銷(xiāo)毀,就看對(duì)象的引用計(jì)數(shù)是否為0
為0的銷(xiāo)毀,不為0的就不銷(xiāo)毀
getrefcount函數(shù)(對(duì)象):獲取對(duì)象的引用計(jì)數(shù)
from sys import getrefcount#
def main():
list1 = [1,2]
#使用不同的變量存對(duì)象地址會(huì)增加引用計(jì)數(shù)
list2 = list1
print(getrefcount(list1))
pass