01-privatization of attributes 屬性的私有化
02-False private attribute getter and setter 假的私有屬性
03-class fields and method 類字段和類方法
04-static method 靜態(tài)方法
05-inheritance of class 類的繼承
06-class inheritance override 類的繼承重寫(掌握)
01-privatization of attributes 屬性的私有化
屬性的訪問權(quán)限:公開、保護(python中沒有)、私有
公開:指的是在類的外部可以直接使用(默認)
公開屬性:屬性名是普通單詞
私有:只能在類的內(nèi)部直接使用
私有屬性:屬性名以兩個下劃線開頭'__'(不以兩個下劃線結(jié)束)
class Person:
"""人"""
def __init__(self, name='', age=0):
# name屬性是公開的屬性
self.name = name
# __age屬性是私有的屬性
self.__age = age
def show(self):
# 私有屬性可以在類的內(nèi)部去使用
print(self.__age)
p1 = Person('小明')
print(p1.name)
# 私有屬性不能在類的外部去使用
# print(p1.age) # value:AttributeError: 'Person' object has no attribute 'age'
p1.show()
02-False private attribute getter and setter 假的私有屬性
實際開發(fā)中边臼,聲明類的屬性,很少會使用真正的私有屬性和公開屬性(前面加兩個下劃線的)
實際對屬性的要求:
1.可以通過 對象.屬性 語法方便的來給屬性賦值或者拿到它的值(不能是私有的)
2.給屬性賦值的時候堂淡,需要對賦過來的值進行規(guī)范,不能直接就讓值賦給屬性(不能是直接的公開屬性)
滿足要求:就是假的私有屬性+getter和setter
1.聲明屬性贿肩,屬性名前加一個下劃線(這個是規(guī)范苍凛,不是語法:帶一個下劃線的屬性,不要直接使用)
2.通過給屬性添加getter和setter來限制賦值和獲取值的過程
a.添加getter:-->限制獲取屬性值的操作
getter的作用:返回屬性的值
@property
def 屬性名去掉下劃線(self):
其他任何操作
return self.帶下滑線的屬性名
b.setter-->限制添加屬性值的操作
setter的作用:修改屬性的值
@屬性名去掉下滑線.setter
def 屬性名去掉下劃線(self, 參數(shù)):
其他任何操作
self.帶下劃線的屬性名 = 參數(shù)
3.在類的外部通過不帶下劃線的屬性去獲取屬性的值粮彤,或者給屬性賦值
示例一:
class Person:
def __init__(self, name, age):
# 聲明屬性的時候根穷,在屬性名前加_,是為了告訴別人,這屬性不要直接訪問导坟,要通過getter或者setter
self._name = name
self._age = age
@property
def name(self):
if len(self._name) == 0:
return '無名氏'
return self._name
# 給_name屬性添加setter
@name.setter
def name(self, name1):
# 可以在給屬性賦值前做其他操作
if isinstance(name1, str):
self._name = name1
else:
self._name = ''
@property
def age(self):
return self._age
@age.setter
def age(self, age1):
if isinstance(age1, int):
self._age = age1
else:
print('請重新賦值')
p1 = Person('xi_ao_ming', 9)
# print(p1._name) # 是不會報錯屿良,但不推薦使用
# p1._name = '路飛'
p1.name = '娜美'
print(p1.name)
print(p1.age)
p1.age = 0
print(p1.age)
getter一般要添加, setter可以不用寫
如果要添加setter必須添加getter
示例二:getter 和 setter的使用以及關(guān)系
class Cat:
"""貓"""
def __init__(self, name='', color=''):
self._name = name
self._color = color
@property
def name(self):
return self._name
cat1 = Cat('小花', 'yellow')
cat1._name = '喵喵' # 推薦
print(cat1._name) #顯示波浪線-->不推薦
getter 與 setter限制類型的使用
練習
class Student:
"""學生"""
def __init__(self, name='', score=0):
self._name = name
self._score = score
# 在getter中限制類型
@property
def name(self):
if isinstance(self._name, str):
return self._name
return 'sdg'
# 在setter中限制類型
@property
def score(self):
return self._score
@score.setter
def score(self, score1):
if isinstance(score1, int) or isinstance(score1, float):
self._score = score1
else:
print('please input number')
s1 = Student()
s1._name = 'st'
print(s1.name)
s1.score = 3.9
print(s1.name,s1.score)
03-class fields and method 類字段和類方法
3.1.類字段就是類屬性:通過類去獲取
類字段是聲明在類里面惫周,函數(shù)外面的變量
3.2.類方法:通過類去調(diào)用
格式:
@classmethod -->函數(shù)修飾符
def 函數(shù)名(cls): -->默認參數(shù)cls尘惧,系統(tǒng)會自動將調(diào)用方法的類傳給它
語句塊
注意:聲明成對象方法還是類方法:看實現(xiàn)的功能是否需要對象屬性來支持,如果需要闯两,必須聲明成對象方法
class Person:
"""
人類
"""
# 這個person_num就是一個類字段
person_num = 60e8
# @classmethod來說明下面的函數(shù)是一個類方法 -->函數(shù)修飾符
# 所有的類方法都有一個默認參數(shù)cls褥伴,這個參數(shù)不需要傳參,系統(tǒng)會自動將調(diào)用方法的類傳個它
@classmethod
def hurt_earth(cls):
print(cls)
print('human damages the environment ,hurt earth',Person.person_num,cls.person_num)
# 類字段要用類去使用
print(Person.person_num)
# 通過Person類調(diào)用類方法
Person.hurt_earth()
print(Person)
# 類字段要用類去使用
print(Person.person_num)
練習:寫一個數(shù)學類漾狼,提供數(shù)據(jù)的加、減饥臂、乘逊躁、除的功能
class Math:
@classmethod
def add(cls,*num):
sum1 = 0
for x in num:
sum1 += x
return sum1
@classmethod
def divide(cls, num1, num2):
return num1/num2
re = Math.add(10, 2, 4)
print(re)
04-static method 靜態(tài)方法
靜態(tài)函數(shù):在類中聲明,由類來調(diào)用的方法
示例一:靜態(tài)方法
class Math:
"""數(shù)學類"""
# multiply就是一個靜態(tài)方法
@staticmethod
def multiply(num1, num2):
return num1*num2
# 靜態(tài)方法需要使用類來調(diào)用
print(Math.multiply(2, 4))
示例二:靜態(tài)方法和類方法的區(qū)別
共同點:都需要用類名去調(diào)用
區(qū)別:
1.類方法都有一個默認參數(shù)cls指向調(diào)用方法的類隅熙,但靜態(tài)方法沒有
2.類型不一樣稽煤,靜態(tài)方法的類型是function,類方法的類型是method
class Download:
"""下載類"""
# 靜態(tài)方法
@staticmethod
def download_image(image_file):
print('download picture in %s ' % image_file)
# 類方法
@classmethod
def download_movie(cls, movie_file):
print('download movie in %s' % movie_file)
# 類中的普通函數(shù)囚戚,也是同過類來調(diào)用
def down(num):
print('aaa', num)
Download.download_image('aa/123.png')
print(Download.download_image) # <function Download.download_image at 0x0038B8A0>
Download.download_movie('aa/safa.avi')
print(Download.download_movie) #<bound method Download.download_movie of <class '__main__.Download'>>
Download.down(234)
print(Download.down) # <function Download.down at 0x0038B810>
print(Download.__dict__)
05-inheritance of class 類的繼承
繼承:繼承就是讓子類去擁有父類的屬性和方法
子類:繼承者
父類(超類):被繼承者
什么時候用繼承:
在寫一個類的時候酵熙,發(fā)現(xiàn)這個類中的部分屬性和方法另一個類都擁有,
這個時候就不用去聲明這些屬性和方法,直接從另外一個類中繼承下來就可以了
5.1:怎么繼承
class 子類(父類):
子類的類容
class Person:
"""人"""
def __init__(self, name='aaa', age=55):
self.name = name
self.age = age
class Student(Person):
pass
stu1 = Student()
print(stu1.name)
5.2:可以繼承哪些東西驰坊?
1.公開屬性可以繼承;私有屬性不能繼承
2.公開的對象方法可以繼承匾二;私有的不行
3.類字段可以
4.類的方法和靜態(tài)方法可以
總結(jié):屬性和方法除了私有的都可以繼承;slots不能繼承
class Animal:
# 1.對象的屬性
__slots__ = ('name', '__age')
def __init__(self, name='abc', age=55):
self.name = name
self.__age = age
def run(self):
print(self.__age)
# 2.對象方法
def eat(self):
print('eat food')
# 私有的對象方法,只能在類的內(nèi)部調(diào)用
def __shout(self):
print('shout')
# 3.類字段
count = 100
# 4.類方法
@classmethod
def class_func(cls):
print('class_func')
# 5.靜態(tài)方法
@staticmethod
def static_func():
print('static_func')
pass
class Dog(Animal):
# def eat_bone(self):
# print('eat bone'. self.__age)
pass
a = Animal()
a.run()
dog1 = Dog()
# dog1.eat_bone()
print(dog1.name)
# print(dog1.age)
print(Dog.count)
Dog.class_func()
Dog.static_func()
dog1.color = 'red'
print(dog1.color)
06-class inheritance override 類的繼承重寫(掌握)
聲明一個類拳芙,如果不聲明其父類察藐,那么這個類默認繼承自object這個類;
object類是python中所有類直接或者間接的父類
6.1示例一:什么是重寫
1.重新實現(xiàn)從父類繼承下來的方法-->重寫
2.super().方法名()
class Animal(object):
def __init__(self, name):
self.name = name
def shout(self):
print('%s: auf!auf!auf!' % self.name)
def be_beat(self):
print(self.name,'is running')
print('auf!auf!auf!when running')
class Dog(Animal):
# 重寫父類的shout方法舟扎,然后通過Dog對象調(diào)用shout執(zhí)行的是子類的方法
def shout(self):
print('%s: alf!alf!alf!' % self.name)
# 重寫父類的be_beat分飞,保留了父類的功能,并且添加新的功能
# super()-->父類
def be_beat(self):
super().be_beat()
print('angry and bite person')
pass
dog1 = Dog('da_huang')
dog1.shout()
dog1.be_beat()
6.2:init方法的繼承和重寫
重寫init方法要注意:
1.如果需要繼承父類的對象屬性睹限,就需要通過supr().init()
去保留父類的對象屬性譬猫,然后再添加新的屬性;
2.父類的參數(shù)必須寫在init后的括號里
class Person:
"""人"""
def __init__(self, name='', age=0):
self.name = name
self.age = age
class Student(Person):
"""
重寫init方法要注意:
1.如果需要繼承父類的對象屬性讯檐,就需要通過supr().__init__()去保留父類的對象屬性棺耍,然后再添加新的屬性
"""
def __init__(self, name='aas', age=0, study_id = ''):
super().__init__(name, age)
self.study_id = study_id
pass
stu1 = Student()
print(stu1.study_id)
print(stu1.name)
stu2 = Student('ada', 23, '002')
print(stu2.name)
stu3 = Student(study_id= '003')
print(stu3.study_id)
練習:
寫一個正方形類锡足,擁有方法:求面積、求周長斯入;擁有屬性邊長
寫一個長方形類肌索,擁有方法:求面積蕉拢、求周長;擁有屬性長和寬
重點:用getter和setter方法將正方形的邊長付給引用的父類(長和寬)
class Rectangle:
"""長方形"""
def __init__(self, length=0, width=0):
self.length = length
self.width = width
def area(self):
return self.length*self.width
def circumference(self):
return (self.length + self.width)*2
class Square(Rectangle):
"""
正方形
"""
def __init__(self, length=0, width=0):
super().__init__(length,width)
self._side = 0
@property
def side(self):
return self._side
@side.setter
def side(self, side):
self.length = side
self.width = side
self._side = side
rec1 = Rectangle(3, 5)
print('>>',rec1.area(), rec1.circumference())
squ1 = Square()
squ1.side = 10
print('>>',squ1.area(), squ1.circumference())