回顧
1.類的聲明
類是擁有相同屬性和相同功能的對象的集合
'''
class 類名:
類的內容
'''
2.創建對象
對象 = 類()
3.(重點)類中的內容:對象方法、類方法、靜態方法;字段、對象屬性
'''
1)方法 -- 怎么聲明、特點、怎么調用、什么時候用
對象方法:直接聲明在類中的函數;有默認參數self;通過對象調用;實現函數功能需要用到對象屬性的時候。
類方法:聲明前加@classmethod;有默認參數cls;通過類調用;實現函數功能不需要對象屬性,需要類相關操作的時候
靜態方法:聲明前加@staticmethod;沒有默認參數;通過類調用;既不需要對象屬性,也不需要類相關操作
2)屬性 -- 怎么聲明、怎么使用、什么時候用
字段:聲明在類里面,函數的外面;通過類來使用;不會因為對象不同而不同的屬性聲明成字段
對象屬性:以'self.屬性 = 值'的形式聲明在init方法中;通過對象使用;會因為對象不同而不同的屬性聲明成對象屬性
'''
4.對象屬性的增刪改查
'''
對象.屬性/getattr() -- 查
對象.屬性 = 值/setattr() -- 增、改
del 對象.屬性/delattr() -- 刪
屬性
1.內置類屬性
創建類的時候,系統默認為我們添加的類的屬性
class Person:
'''人類'''
# 類的字段
number = 61
# 對象屬性
def __init__(self, name, age, gender='女'):
self.name = name
self.age = age
self.gender = gender
# ============方法============
def object_func(self):
print('對象方法:'+self.name)
@classmethod
def class_func(cls):
print('類方法:',cls.number)
@staticmethod
def static_func():
print('靜態方法')
'''
#系統自帶的魔法,可以定制當前類的對象的打印內容。實現這個函數要求有一個字符串類型的返回值
# 影響單獨打印對象的效果
# def __str__(self):
# return str(self.__dict__)
'''
# 對象作為元素的時候的打印效果
def __repr__(self):
return 'abc'
p1 = Person('小明', 18, '男')
print('p1:',p1)
persons = [p1,Person('小花',20)]
print(persons)
1).name 字段
'''
類.name -- 獲取類的名字
'''
print(Person.name)
2).doc 字段
'''
類.doc -- 獲取類的說明文檔
'''
print(Person.doc)
3).class 對象屬性
'''
對象.class -- 獲取對象對應的類(你這個對象是哪個類的對象)
'''
print(p1.class)
4).dict 字段和對象屬性都可以
'''
類.dict -- 獲取類中所有的字段和對應的值,以字典的形式返回(了解)
對象.dict -- 獲取對象中所有的屬性和對應的值,以字典的形式返回(掌握)
'''
print(Person.dict)
print(p1.dict)
5).module 字段
'''
類.module -- 獲取指定的類聲明在哪個模塊中,返回模塊名(獲取類所在的模塊的name屬性值)
'''
print(Person.module)
6).bases 字段
'''
類.bases -- 返回當前類的所有父類
'''
print(Person.bases)
2.slots魔法
'''
可以通過slots字段賦值來約束當前有哪些對象屬性
當在類中給slots賦值后,當前類的對象的dict屬性無效
'''
class Dog:
#__slots__ = ('name','age','gender','name1')
def __init__(self, name, age=0):
self.name = name
self.age = age
self.gender = '公'
dog = Dog('大黃')
dog.name1 = '小白'
#dog.x = 12
print(dog.__dict__)
私人、保護
'''
1.高級語言
在很多的高級面向對象語音中,會將屬性和方法分為公開的(在類的外部可以使用)、私有的(只能在類的內部使用,不能被繼承)、受保護(只能在類的內部使用,可以被繼承)
2.python
python中類的內容本質上全部是公開的。私有和公開都只是約定
1)私有化 -- a.內容只能在類的內部使用,不能再外面使用。(效果)
b.在類中的方法名或者屬性名前加'',那么對應的屬性和方法就會變成私有的
c.當聲明類的時候在名字前加'',內部會在這個基礎前面再加'_類名'。(本質)
2)屬性保護 -- 可通過在對象屬性前加'_',把這個屬性標記成為保護類型;為了告訴別人這個
屬性在使用的時候不要直接用,而是通過getter和setter來用
a.getter -- 獲取對象的屬性值之前想要干點別的事情,那么就給這個屬性添加getter
第一步:在對應的屬性名前加''
第二步:在@property后面聲明一個函數,這個函數沒有參數,有一個返回值,并且函數名是屬性名去掉''
第三步:獲取屬性值的時候,通過對象.屬性名去掉下劃線去獲取屬性的值
b.setter -- 給屬性賦值前干別的事情,就給這個屬性天劍setter。(想要添加setter必須先有getter)
第一步:在對應的屬性前面加''
第二步:在@getter名.setter后面聲明一個函數,這個函數需要一個參數,沒有返回值,并且函數名是屬性名去掉''
第三步:給屬性賦值的時候,通過'對象.屬性名去掉下劃線=值'的方式賦值
3.拋出異常:
a.語法
raise 異常類型
b.說明:
raise -- 關鍵字
異常類型 -- 可以是系統提供的異常類型,也可以是自定義異常類型(必須繼承Exception)
4.自定義異常類型:寫一個類繼承Exception,然后重寫str方法來自定義錯誤信息
'''
# ===============自定義異常=============
class WeekValueError(Exception):
def __str__(self):
return '星期的值只能是1-7的整數!'
# raise WeekValueError
# =================保護===============
class Person1:
def __init__(self):
self.age = 0
self._week = 1
@property
def week(self):
return '星期一'
@week.setter
def week(self,x):
if not isinstance(x, int):
raise ValueError
elif not 1 <= x <= 7:
raise ValueError
self.week = x
p1 = Person1()
p1.age = 100
p1.age = 1000
p1.age = 'abc'
#p1.week = 4 #本質是在調用setter對應的方法
print(p1.week) #本質在調用getter對應的方法
練習:給age屬性添加getter和setter,獲取年齡的時候拿到年齡值,和這個年齡對應的階段給age賦值的時候,必須是整數,并且范圍在0-120。如果不滿足要求報錯:AgeError
class AgeError(Exception):
def __str__(self):
return '年齡必須是整數,并且范圍在0-120!'
class Person2:
def __init__(self):
self._age = 0
@property
def age(self):
if self._age < 18:
return self._age,'未成年'
else:
return self._age,'成年'
@age.setter
def age(self, x):
if not isinstance(x, int):
raise AgeError
elif not 0 <= x <= 120:
raise AgeError
self._age = x
p2 = Person2()
p2.age = 100
print(p2.age)
# ================私有化==============
class Person:
def __init__(self, name, age=10):
self.name = name
self.__age = age
def message(self):
print(self.__age)
p = Person('小明')
print(p.name)
#p.message()
#print(p.__age)
print(p._Person__age)
繼承
1.什么是繼承:讓子類直接擁有父類的所有的屬性和方法
父類 -- 被繼承者, 子類 -- 繼承者
python中所有的類都是直接或間接的繼承object
2.怎么繼承
'''
class 子類(父類列表):
類的內容
'''
3.子類中的添加內容
'''
1)添加字段和方法,直接添加
'''
class Person(object):
number = 61
def __init__(self):
self.name = '小明'
self.age = 18
self.gender = '男'
def fun1(self):
print(self.name)
@classmethod
def func2(cls):
print(cls.number)
@staticmethod
def func3():
print('func3')
class Student(Person):
flag = '學生!'
def __init__(self):
# 在子類的方法中調用父類的屬性
super().__init__()
self.study_id = 'stu0001'
pass
# 使用父類繼承下來的屬性和方法
print(Student.number)
stu = Student()
print(stu.name)
print(stu.age)
print(stu.gender)
stu.fun1()
stu.func2()
stu.func3()
print(stu.__dict__)
print(Student.__dict__)