|
過程和函數(shù):過程類似于函數(shù),只能執(zhí)行,但是沒有返回結(jié)果;函數(shù)不僅能執(zhí)行,還能返回結(jié)果。 面向過程和面向?qū)ο?基本概念 面向過程-怎么做
特點(diǎn)
面向?qū)ο?誰來做 相比較函數(shù),面向?qū)ο笫歉蟮姆庋b,根據(jù)職責(zé)在一個(gè)對象中封裝多個(gè)方法。
特點(diǎn)
面向?qū)ο笫腔诿嫦蜻^程的 用面向?qū)ο蟮乃季S解決問題的重點(diǎn) 當(dāng)遇到一個(gè)需求的時(shí)候不用自己去實(shí)現(xiàn),如果自己一步步實(shí)現(xiàn)那就是面向過程;應(yīng)該找一個(gè)專門做這個(gè)事的人來做。 面向?qū)ο?object-oriented ;簡稱: OO) 至今還沒有統(tǒng)一的概念 我們可以把它定義為: 按人們 認(rèn)識(shí)客觀世界的系統(tǒng)思維方式,采用基于對象(實(shí)體) 的概念建立模型,模擬客觀世界分析、設(shè) 計(jì)、實(shí)現(xiàn)軟件的辦法。 面向?qū)ο缶幊?Object Oriented Programming-OOP) 是一種解決軟件復(fù)用的設(shè)計(jì)和編程方法。 這種方法把軟件系統(tǒng)中相近相似的操作邏輯和操作 應(yīng)用數(shù)據(jù)、狀態(tài),以類的型式描述出來,以對象實(shí)例的形式在軟件系統(tǒng)中復(fù)用,以達(dá)到提高軟件開發(fā)效率的作用。 Python學(xué)習(xí)交流群:1004391443,這里是python學(xué)習(xí)者聚集地,有大牛答疑,有資源共享!小編也準(zhǔn)備了一份python學(xué)習(xí)資料,有想學(xué)習(xí)python編程的,或是轉(zhuǎn)行,或是大學(xué)生,還有工作中想提升自己能力的,正在學(xué)習(xí)的小伙伴歡迎加入學(xué)習(xí)。 類和對象 類和對象的概念 類 類是對一群具有相同特征或者行為的事物的一個(gè)統(tǒng)稱,是抽象的,不能直接使用; 特征被稱為屬性; 行為被稱為方法。 對象 對象是由類創(chuàng)建出來的一個(gè)具體存在,可以直接使用; 由哪一個(gè)類創(chuàng)建出來的對象,該對象就具有在那一個(gè)類中定義的屬性和方法; 類和對象的關(guān)系 類就是創(chuàng)建對象的模板,應(yīng)該先有類,在有對象; 一個(gè)類可以創(chuàng)建多個(gè)對象,不同對象之間屬性可能各不相同; 類中定義了什么方法,對象中就有什么屬性和方法,不可能少,但可能多,因?yàn)閷ο罂梢宰约涸陬愅庠黾訉傩?/p> 類的設(shè)計(jì) 在使用面向?qū)ο箝_發(fā)前,應(yīng)該首先分析需求,確定一下,程序中需要包含哪些類。 在程序開發(fā)中,要設(shè)計(jì)一個(gè)類,通常要滿足以下三個(gè)要素
屬性和方法的確定 對 對象的特征描述,通常可以定義為屬性 對象具有的行為,通??梢远x為方法 面向?qū)ο蠡A(chǔ)語法 dir內(nèi)置函數(shù) 在Python中對象幾乎是無所不在的,我們之前學(xué)習(xí)的變量,數(shù)據(jù),函數(shù)都是對象; 在Python中可以使用以下兩個(gè)方法驗(yàn)證:
部分內(nèi)置方法說明 ? image 在交互式下: def demo():
'''這是一個(gè)測試函數(shù)'''
print('hello python')
dir(demo)
['__annotations__', '__call__', '__class__', '__closure__', '__code__',
'__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__',
'__format__', '__ge__', '__get__', '__getattribute__', '__globals__',
'__gt__', '__hash__', '__init__', '__init_subclass__', '__kwdefaults__',
'__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__',
'__qualname__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
'__sizeof__', '__str__', '__subclasshook__']
demo.__doc__
'這是一個(gè)測試函數(shù)'
定義簡單的類 面向?qū)ο笫歉蟮姆庋b,在一個(gè)類中封裝多個(gè)方法,這樣通過這個(gè)類創(chuàng)建出來的對象,就可以直接調(diào)用這些方法了。 定義只包含方法的類 在python中藥定義一個(gè)只包含方法的類,語法格式如下: class 類名: def 方法1(self, 列表參數(shù)): pass def 方法2(self, 列表參數(shù)): pass 方法的定義格式和之前學(xué)習(xí)的函數(shù)幾乎一樣; 區(qū)別在于第一個(gè)參數(shù)必須是self; 注意,類名的命名規(guī)則要符合大駝峰命名法; 創(chuàng)建對象 當(dāng)一個(gè)類定義完成后,要使用這個(gè)類來創(chuàng)建對象,語法格式如下: 對象變量 = 類名()
第一個(gè)面向?qū)ο蟪绦?/p> class Cat:
'''定義一個(gè)貓類'''
def eat(self):
print('小貓愛吃魚')
def drink(self):
print('小貓要喝水')
tom = Cat()
tom.eat()
tom.drink()
引用概念的強(qiáng)調(diào)
Python學(xué)習(xí)交流群:556370268,這里是python學(xué)習(xí)者聚集地,有大牛答疑,有資源共享!小編也準(zhǔn)備了一份python學(xué)習(xí)資料,有想學(xué)習(xí)python編程的,或是轉(zhuǎn)行,或是大學(xué)生,還有工作中想提升自己能力的,正在學(xué)習(xí)的小伙伴歡迎加入學(xué)習(xí)。 驗(yàn)證引用示例 class Cat:
'''定義一個(gè)貓類'''
def eat(self):
print('小貓愛吃魚')
def drink(self):
print('小貓要喝水')
tom = Cat()
tom.eat()
tom.drink()
print(tom) # <__main__.Cat object at 0x0000019D74C30C18>
addr = id(tom)
print('%d' % addr) # 以十進(jìn)制表示地址 1775780432920
print('%x' % addr) # 以十六進(jìn)制表示地址 19d74c30c18
一個(gè)類創(chuàng)建多個(gè)對象 示例 class Cat:
'''定義一個(gè)貓類'''
def eat(self):
print('小貓愛吃魚')
def drink(self):
print('小貓要喝水')
tom = Cat()
bosi = Cat()
bosi2 = bosi
print(tom) # <__main__.Cat object at 0x000001A4A0B1FB70>
print(bosi) # <__main__.Cat object at 0x000001A4A0B1FC50>
print(bosi2) # <__main__.Cat object at 0x000001A4A0B1FC50>
方法中的self函數(shù) 在類外給對象附加屬性
類外給對象附加屬性示例 class Cat:
'''定義一個(gè)貓類'''
def eat(self):
print('小貓愛吃魚')
def drink(self):
print('小貓要喝水')
tom = Cat()
tom.name = '湯姆'
bosi = Cat()
bosi.name = '波斯'
利用self 在 類封裝的方法中 輸出對象屬性 由哪一個(gè)對象調(diào)用的方法,方法內(nèi)的self就是哪一個(gè)對象的引用; 在類封裝的方法內(nèi)部,self就表示當(dāng)前調(diào)用方法的對象自己; 調(diào)用方法時(shí),不需要傳遞self參數(shù); 在類的外部,通過變量名. 訪問對象的屬性和方法; 在類封裝的方法內(nèi)部中,通過self. 訪問對象的屬性和方法。 class Cat:
'''定義一個(gè)貓類'''
# 哪一個(gè)對象調(diào)用的方法,方法內(nèi)的self就是哪一個(gè)對象的引用
def eat(self):
print('%s愛吃魚' % self.name)
def drink(self):
print('%s要喝水' % self.name)
tom = Cat()
tom.name = '湯姆'
tom.eat()
tom.drink()
bosi = Cat()
bosi.name = '波斯'
bosi.eat()
bosi.drink()
# 湯姆愛吃魚
# 湯姆要喝水
# 波斯愛吃魚
# 波斯要喝水
在類外給對象增加屬性的問題 如果是在調(diào)用方法之后,才設(shè)置的屬性,并且調(diào)用的方法要用到屬性,那么就會(huì)報(bào)錯(cuò)。 class Cat:
'''定義一個(gè)貓類'''
# 哪一個(gè)對象調(diào)用的方法,方法內(nèi)的self就是哪一個(gè)對象的引用
def eat(self):
print('%s愛吃魚' % self.name)
def drink(self):
print('%s要喝水' % self.name)
tom = Cat()
tom.eat() # 報(bào)錯(cuò)
tom.drink() # 報(bào)錯(cuò)
tom.name = '湯姆'
因此,在日常開發(fā)中,不推薦在類的外部給對象增加屬性; 對象應(yīng)該包含有哪些屬性,應(yīng)該封裝在類的內(nèi)部。 初始化方法 當(dāng)使用 類名()創(chuàng)建對象時(shí),會(huì)自動(dòng)執(zhí)行以下操作:
這個(gè)初始化方法就是 init 方法, init 是對象的內(nèi)置方法; init方法是專門用來定義一個(gè)類具有哪些屬性的方法; 在我們用類創(chuàng)建一個(gè)對象時(shí),如果類中有初始化方法,會(huì)自動(dòng)調(diào)用初始化方法。 例如以下代碼,當(dāng)我們創(chuàng)建對象時(shí),就算不調(diào)用方法,也會(huì)輸出 “初始化方法”。 class Cat:
def __init__(self):
print('初始化方法')
tom = Cat() # 初始化方法
在初始化方法中定義屬性 在 init 方法內(nèi)部使用 self.屬性名 = 屬性的初始值 就可以定義屬性; 定義屬性后,再使用Cat類創(chuàng)建的對象,都會(huì)擁有該屬性; class Cat:
def __init__(self):
print('初始化方法')
# self.屬性名 = 屬性的初始值
self.name = '湯姆'
def eat(self):
print('%s愛吃魚' % self.name)
tom = Cat()
print(tom.name)
使用參數(shù)設(shè)置屬性初始值 在開發(fā)中,如果希望創(chuàng)建對象的同時(shí),就設(shè)置對象的屬性,可以對 init 方法進(jìn)行改進(jìn)。
參數(shù)設(shè)置屬性初始值示例 class Cat:
def __init__(self, new_name):
# self.屬性名 = 形參
self.name = new_name
def eat(self):
print('%s愛吃魚' % self.name)
tom = Cat('湯姆')
tom.eat()
bosi = Cat('波斯')
bosi.eat()
# 湯姆愛吃魚
# 波斯愛吃魚
內(nèi)置方法和屬性 del方法 del 方法 會(huì)在 執(zhí)行完所有代碼后系統(tǒng)自動(dòng)銷毀對象變量; 因?yàn)閠om是全局對象,所以正常運(yùn)行時(shí) 會(huì)在所有代碼結(jié)束后自動(dòng)調(diào)用 del 方法; 如果使用了del關(guān)鍵字刪除tom的全局變量,則會(huì)在執(zhí)行del tom前 就會(huì)自動(dòng)調(diào)用 del 方法銷毀對象內(nèi)存; 應(yīng)用場景 init改造初始化方法,可以讓創(chuàng)建對象更加靈活; del如果希望在對象被銷毀前,再做一些事情,可以考慮使用 del 方法; 生命周期 一個(gè)對象從調(diào)用 類名()創(chuàng)建對象,生命周期開始; 一個(gè)對象的 del 方法一旦被調(diào)用,生命周期結(jié)束; 在對象的生命周期之內(nèi),可以訪問對象屬性,或者讓對象調(diào)用方法。 class Cat:
def __init__(self, new_name):
# self.屬性名 = 屬性的初始值
self.name = new_name
print('%s init' % self.name)
def __del__(self):
print('%s del' % self.name)
def eat(self):
print('%s愛吃魚' % self.name)
tom = Cat('湯姆')
tom.eat()
print('-'*50)
# 湯姆 init
# 湯姆愛吃魚
# --------------------------------------------------
# 湯姆 del
沒執(zhí)行完所有代碼就刪除tom對象 class Cat:
def __init__(self, new_name):
# self.屬性名 = 屬性的初始值
self.name = new_name
print('%s init' % self.name)
def __del__(self):
print('%s del' % self.name)
def eat(self):
print('%s愛吃魚' % self.name)
# tom 是一個(gè)全局變量
tom = Cat('湯姆')
tom.eat()
# 因?yàn)樵趫?zhí)行完所有代碼之前,全局變量tom就被刪除了,所以會(huì)自動(dòng)調(diào)用__del__方法,不會(huì)等-*50的執(zhí)行
del tom
print('-'*50)
# 湯姆 init
# 湯姆愛吃魚
# 湯姆 del
# --------------------------------------------------
str方法 print(變量對象) 默認(rèn)看到父類和變量對象的內(nèi)存地址,但 我們可以通過 str 方法來自定義看到的內(nèi)容 ; 注意, str 方法必須要返回一個(gè)字符串。 class Cat:
def __init__(self, new_name):
# self.屬性名 = 形參
self.name = new_name
def __str__(self):
return '<object_name>-<%s>' % self.name
def eat(self):
print('%s愛吃魚' % self.name)
# tom 是一個(gè)全局變量
tom = Cat('湯姆')
tom.eat()
print(tom)
# 湯姆愛吃魚
# <object_name>-<湯姆>
身份運(yùn)算符is 身份運(yùn)算符介紹 身份運(yùn)算符用于比較兩個(gè)對象的內(nèi)存地址是否一致--是否是對同一個(gè)對象的引用; 注意,在python中針對None比較時(shí),建議使用is判斷; 身份運(yùn)算符表 ? image is和==的區(qū)別 is用于判斷兩個(gè)變量引用對象是否是同一個(gè); ==用于判斷引用變量的值是否相等; a = [1, 2, 3] b = [1, 2] b.append(3) a is b # False a ==b # True 當(dāng)在判斷None時(shí),建議使用is判斷; |
|
|