一.類和對(duì)象
1.什么是類赡模,什么是對(duì)象
類就是擁有相同屬性和相同功能的對(duì)象的集合师抄;類是抽象的
對(duì)象就是累的實(shí)例;對(duì)象是具體的
人是類辆布,xxx就是對(duì)象
車是類谚殊,樓下停在...的那輛車就是對(duì)象
2.類的聲明
類中的內(nèi)容包含功能(函數(shù))和屬性(變量/屬性)
a.語法
class 類名(父類):
類的內(nèi)容
class Person:
"""類的說明文檔:人類"""
num = 61 # 類的屬性
# 類中的方法
def eat(self):
print('人在吃飯')
b.說明
class - python聲明類的關(guān)鍵字
類名 - 要求:標(biāo)識(shí)符嫩絮,不能是關(guān)鍵字
規(guī)范:駝峰式命名(通過首字母大寫來區(qū)分不同單詞),第一個(gè)字母要大寫
userName - 駝峰式
UserName - 類名
user_name - pep8
:- 固定寫法
類的內(nèi)容 - 包含類的方法和屬性蜂怎、說明文檔
方法:就是聲明在類中的函數(shù)
屬性就是聲明在類中的變量
3.對(duì)象的聲明
語法:
類名() - 創(chuàng)建指定的類的對(duì)象
class 類名:
類中的屬性
類中的方法
二.方法
1.類中的方法
聲明在類中的函數(shù)就是方法
類中的方法包括:對(duì)象方法(實(shí)例方法)杠步,實(shí)例幽歼,靜態(tài)方法
2.對(duì)象方法:
直接聲明在類中的方法就是對(duì)象方法
有默認(rèn)參數(shù)self
通過'對(duì)象.方法()'的方式來調(diào)用(對(duì)象方法就要通過對(duì)象來調(diào)用)
當(dāng)我們通過對(duì)象調(diào)用對(duì)象方法的時(shí)候甸私,self不需要傳參皇型;因?yàn)橄到y(tǒng)會(huì)自動(dòng)將對(duì)象傳遞給self
當(dāng)前對(duì)象:調(diào)用當(dāng)前方法的對(duì)象(誰調(diào)用對(duì)象方法self就是誰)
注意:當(dāng)前類和對(duì)象能做的事情self都能做
class Person:
def run(self):
print('人在跑步')
def main():
# 創(chuàng)建對(duì)象
p1=Person()
p1.run()
# 通過對(duì)象p1調(diào)用對(duì)象方法只需要給除了self以外的對(duì)象傳參
p2 = Person()
p2.run()
三.init方法
1.init方法: init
init方法是類中的一個(gè)特殊的對(duì)象方法,專門用來對(duì)象創(chuàng)建的對(duì)象進(jìn)行初始化弃鸦。
當(dāng)通過類創(chuàng)建對(duì)象的時(shí)候唬格,系統(tǒng)就會(huì)自動(dòng)調(diào)用init方法
2.構(gòu)造方法
a.什么是構(gòu)造方法
函數(shù)名和類名一樣的函數(shù)就是構(gòu)造方法雪隧, 專門用來創(chuàng)建對(duì)象。
python中聲明類的時(shí)候系統(tǒng)會(huì)自動(dòng)創(chuàng)建這個(gè)類對(duì)應(yīng)的構(gòu)造方法藕畔。
b.構(gòu)造方法的執(zhí)行過程
當(dāng)我們構(gòu)造方法的時(shí)候內(nèi)部會(huì)先在內(nèi)存中開辟空間保存對(duì)象;然后用創(chuàng)建的這個(gè)對(duì)象去調(diào)用inin方法,用來對(duì)對(duì)象進(jìn)行初始化;
init方法調(diào)用結(jié)束后注服,返回對(duì)象.
def Person(*args, *kwargs):
對(duì)象 = 創(chuàng)建對(duì)象
對(duì)象.init(args, **kwargs)
return 對(duì)象
注意: 如果類的init方法除了self以外還有其他參數(shù),那么我們?cè)趧?chuàng)建對(duì)象的時(shí)候需要通過給構(gòu)造方法來給init方法傳參女淑。
class Dog:
def __init__(self, x=0, y=9):
print(x, y)
print('dog的init')
四.對(duì)象屬性
1.什么是對(duì)象屬性
類中的屬性分為類的字段和對(duì)象屬性
a.對(duì)象屬性 - 屬性的值會(huì)因?yàn)閷?duì)象不同而不一樣鸭你,這種屬性就應(yīng)該聲明為對(duì)象屬性
聲明在init方法中 - 位置
以'self.屬性名 = 值'的方式來聲明(這兒的屬性就是對(duì)象屬性) - 方式
通過'對(duì)象.屬性'的方式來使用 - 使用
b.類的字段 - 屬性的值不會(huì)因?yàn)閷?duì)象不同而不同袱巨,這種屬性就聲明成類的字段
直接聲明類的里面,函數(shù)的外面的變量就是類的字段
以'字段名 = 值'
通過'類.字段'的方式來使用
class Person:
# num就是類的字段
num = 61
# 在init方法中聲明對(duì)象屬性
def __init__(self, name='', age=0):
self.name = name
self.age = age
練習(xí):創(chuàng)建Dog類剖效,有屬性名字璧尸、類型逗宁、年齡
要求創(chuàng)建Dog的對(duì)象的時(shí)候:不能給年齡賦值,可以給類型賦值也可以不用給類型賦值,必須給名字賦值
對(duì)象方法eat:打印XXX在吃什么
class Dog:
def __init__(self, name, type='土狗'):
self.name = name
self.age = 0
self.type = type
def eat(self, food):
# self = dog1, food = '骨頭'
# self = dog2, food = '屎'
print('%s在吃%s' % (self.name, food))
五.增刪改查
1.屬性的增刪改查
class Person:
def __init__(self, name='', age=0, sex='女'):
self.name = name
self.age = age
self.sex = sex
slots魔法:約束當(dāng)前類的對(duì)象最多能擁有那個(gè)屬性
class Dog:
# __slots__魔法
# 約束當(dāng)前類的對(duì)象最多能擁有那個(gè)屬性
__slots__ = ('name', 'color', 'age', 'sex')
def __init__(self, name='', color='黑色'):
self.name = name
self.color = color
self.age = 10
1.查(獲取對(duì)象屬性)
對(duì)象.屬性 - 獲取指定對(duì)象指定屬性值;當(dāng)屬性不存在的時(shí)候會(huì)報(bào)錯(cuò)
getattr(對(duì)象, 屬性名:str, 默認(rèn)值) - 獲取指定對(duì)象指定屬性值;
當(dāng)屬性不存在的時(shí)候如果給默認(rèn)值賦了值,程序不會(huì)報(bào)錯(cuò)倦逐,并且將默認(rèn)值作為結(jié)果
print('==============查===================')
print(p1.name)
# print(p1.name1) # AttributeError:'Person' object has no attribute 'name1'
# 屬性不確定的時(shí)候可以使用getattr
# attr = input('屬性:')
# print(getattr(p1, attr))
print(getattr(p1, 'name', None))
print(getattr(p1, 'name1', None))
- 增/改
對(duì)象.屬性 = 值 - 當(dāng)屬性存在的是修改屬性的值;屬性不存在的時(shí)候添加屬性
setattr(對(duì)象, 屬性名, 值) - 當(dāng)屬性存在的是修改屬性的值粉怕;屬性不存在的時(shí)候添加屬性
print('==============增/改===================')
# 修改屬性
p1.name = 'xiaohua'
print(p1.name)
# 添加屬性
p1.height = 180
print(p1.height)
3.刪
del 對(duì)象.屬性
delattr(對(duì)象, 屬性名)
print('==============刪=================')
del p1.sex
# print(p1.sex) # AttributeError: 'Person' object has no attribute 'sex'
delattr(p1, 'age')
# print(p1.age) # AttributeError: 'Person' object has no attribute 'age'
注意:對(duì)象屬性的操作贫贝,只針對(duì)操作的那一個(gè)對(duì)象蛉谜,不會(huì)影響其他對(duì)象
六.內(nèi)置屬性
內(nèi)置屬性指的是我們創(chuàng)建類的時(shí)候系統(tǒng)自動(dòng)給我們添加的屬性(其實(shí)是通過繼承獲取到的)
class Person:
"""說明文檔:人類"""
# 類的字段
num = 61
# __slots__ = ('name', 'age', 'sex')
# 對(duì)象屬性
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))
定制對(duì)象的打印格式(當(dāng)我們通過print打印一個(gè)對(duì)象的時(shí)候,實(shí)質(zhì)就是打印對(duì)象調(diào)用repr函數(shù)的返回值)
# 這個(gè)函數(shù)的返回值必須是字符串
def __repr__(self):
# return '<%s.%s object at %s>' % (self.__class__.__module__, self.__class__.__name__, hex(id(self)))
return '<' + str(self.__dict__)[1:-1] + ' at ' + hex(id(self)) + '>'
def main():
p1 = Person('小明', 18)
print(p1) # print(p1.__repr__())
persons = [Person('p1', 12), Person('p2', 18, '女')]
print(persons)
# 1. 類.__name__ - 獲取的名字(字符串)
print(Person)
class_name = Person.__name__
print(Person, class_name)
# 值是一個(gè)字符串狰贯,可以當(dāng)成字符串來用
print(class_name.upper())
# 2. 對(duì)象.__class__ - 獲取對(duì)象對(duì)應(yīng)的類(結(jié)果是類)
# 獲取對(duì)象p1的類
my_class = p1.__class__
print(my_class)
# 可以將my_class當(dāng)成類來使用
p2 = my_class('小花')
print(my_class.num)
# 3. 類.__doc__ - 獲取類的說明文檔(字符串)
print(Person.__doc__)
print(int.__doc__)
# 獲取對(duì)象p1對(duì)應(yīng)的類的說明文檔
print(p1.__class__.__doc__)
# 4.對(duì)象.__dict__ - 將對(duì)象轉(zhuǎn)換成字典暮现,將屬性和值作為字典的鍵值對(duì)(字典)
# 注意:當(dāng)給__slots__屬性賦值后栖袋,對(duì)象的__dict__屬性就不能使用
print(p1.__dict__)
# 5.類.__module__ - 獲取當(dāng)前類所在的模塊的模塊名
print(Person.__module__)
# 6.類.__bases__ - 獲取當(dāng)前類的父類(元祖)
print(Person.__bases__)
七.類方法和對(duì)象方法
1.對(duì)象方法:
a.怎么聲明: 直接聲明在類型
b.特點(diǎn): 自帶self參數(shù),調(diào)用的時(shí)候不用傳參,誰調(diào)用指向誰
c.怎么調(diào)用: 對(duì)象.方法()
2.類方法:
a.怎么聲明: 聲明函數(shù)前加@classmethod
b.特點(diǎn): 自帶默認(rèn)參數(shù)cls; 調(diào)用的不用傳參塘幅,系統(tǒng)會(huì)自動(dòng)將調(diào)用當(dāng)前函數(shù)的類傳給它
(cls是誰調(diào)用就指向誰, 類方法只能通過類來調(diào)用电媳,所以cls就是當(dāng)前類)
類能做的事情庆亡,cls都能做
c.怎么調(diào)用: 通過類來調(diào)用, 類.方法()
3.靜態(tài)方法
a.怎么聲明:聲明函數(shù)前加@staticmethod
b.特點(diǎn): 沒有默認(rèn)參數(shù)
c.怎么調(diào)用:通過類來調(diào)用, 類.方法()
4.在類中怎么選擇使用哪種方法:
如果實(shí)現(xiàn)類中的函數(shù)的功能需要使用對(duì)象的屬性拼缝, 那么這個(gè)函數(shù)就要聲明對(duì)象方法彰亥。
實(shí)現(xiàn)函數(shù)的功能不需要對(duì)象屬性的前提下任斋,如果需要類的字段继阻, 就聲明稱類方法。
實(shí)現(xiàn)函數(shù)的功能既不需要對(duì)象屬性也不需要類的字段就聲明成靜態(tài)方法废酷。
class Person:
num = 61
def __init__(self):
self.name = '張三'
def func4(self):
print('%s對(duì)應(yīng)的對(duì)象' % self.name)
# print('人類的數(shù)量:%d億' % Person.num)
@staticmethod
def func3():
print(Person.num)
print('我是靜態(tài)方法!')
@classmethod
def func2(cls):
print(cls.num)
print('我是類方法2')
@classmethod
def func1(cls):
# 類能做的,cls都能做
p1 = cls() # 用cls來創(chuàng)建對(duì)象
print(p1)
cls.num = 100 # 用cls來使用類的字段
cls.func2() # 用cls調(diào)用類方法
print('cls:', cls)
print('這是一個(gè)類方法')
def main():
print(Person)
Person.func1()
Person.func3()
p1 = Person()
p1.func4()