特性:
模塊化 流程化
優(yōu)點(diǎn):
性能比面向?qū)ο蟾? 因?yàn)轭愓{(diào)用時(shí)需要實(shí)例化,開銷比較大,比較消耗資源;
單片機(jī)、嵌入式開發(fā)、Linux/Unix等一般采用面向過程開發(fā),性能是最重要的因素。
缺點(diǎn):
沒有面向?qū)ο笠拙S護(hù)、易復(fù)用、易擴(kuò)展
創(chuàng)新互聯(lián)是專業(yè)的云龍網(wǎng)站建設(shè)公司,云龍接單;提供成都做網(wǎng)站、網(wǎng)站設(shè)計(jì)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行云龍網(wǎng)站開發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來合作!
函數(shù)式編程是種編程方式,它將電腦運(yùn)算視為函數(shù)的計(jì)算。函數(shù)編程語言最重要的基礎(chǔ)是λ
演算(lambda calculus),而且λ演算的函數(shù)可以接受函數(shù)當(dāng)作輸入(參數(shù))和輸出(返回值)。
主要思想: 把運(yùn)算過程盡量寫成一系列嵌套的函數(shù)調(diào)用。
面向?qū)ο缶幊?br/>面向?qū)ο笫前慈藗冋J(rèn)識(shí)客觀世界的系統(tǒng)思維方式,把構(gòu)成問題事務(wù)分解成各個(gè)對(duì)象,建立對(duì)
象的目的不是為了完成一個(gè)步驟,而是為了描敘某個(gè)事物在整個(gè)解決問題的步驟中的行為
特性: 抽象 封裝 繼承 多態(tài)
優(yōu)點(diǎn): 易維護(hù)、易復(fù)用、易擴(kuò)展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,
可以設(shè)計(jì)出低耦合 的系統(tǒng),使系統(tǒng)更加靈活、更加易于維護(hù)
缺點(diǎn):
性能比面向過程低
class Student(object):
"""封裝學(xué)生類"""
def __init__(self, sid, name, score1, score2):
"""封裝了學(xué)生屬性信息"""
self.sid = sid
self.name = name
self.score1 = score1
self.score2 = score2
def show(self):
pass
def compute_sum_score(self):
return self.score1 + self.score2
def compute_avg_score(self):
return (self.score1 + self.score2)/2
stu1 = Student(sid='001', name='張三', score1=100, score2=90)
print(stu1.compute_sum_score())
stu2 = Student(sid='002', name='張三', score1=100, score2=100)
print(stu2.compute_avg_score())"""
類(Class) 是現(xiàn)實(shí)或思維世界中的實(shí)體在計(jì)算機(jī)中的反映,它將數(shù)據(jù)以及這些數(shù)
據(jù)上的操作封裝在一起。
對(duì)象(Object) 是具有類類型的變量。類和對(duì)象是面向?qū)ο缶幊碳夹g(shù)中的最基本的概
念。
對(duì)象和類
#class 類名稱: 定義類的方式
class Person:
#占位關(guān)鍵字, 什么也不做
pass
print(Person) # 存儲(chǔ)于當(dāng)前腳本的Person類
#對(duì)象:將類實(shí)例化/具體化產(chǎn)生的值
personObj = Person()
#<__main__.Person object at 0x7f28164b04d0>
#當(dāng)前腳本的Person類實(shí)例化出來的對(duì)象存儲(chǔ)的內(nèi)存地址是0x7f28164b04d0
print(personObj)
#Python自帶的類
from datetime import datetime
from datetime import date
from collections import defaultdict
#構(gòu)造方法__init__與其他普通方法不同的地方在于,當(dāng)一個(gè)對(duì)象被創(chuàng)建后(實(shí)例化),會(huì)立即調(diào)
#用構(gòu)造方法。自動(dòng)執(zhí)行構(gòu)造方法里面的內(nèi)容。
class Student:
# 實(shí)例化對(duì)象的過程中自動(dòng)執(zhí)行的函數(shù)
def __init__(self): # self是形參還是實(shí)參? - 形參
# self是什么? self實(shí)質(zhì)上實(shí)例化出來的對(duì)象。系統(tǒng)自動(dòng)將實(shí)例化的對(duì)象傳遞給構(gòu)造方法。
print("self: ", self)
print("正在運(yùn)行構(gòu)造方法........")
print(Student) #
#實(shí)例化產(chǎn)生對(duì)象的過程
stu1 = Student()
print("stu1: ", stu1)
封裝特性
面向?qū)ο蟮娜筇匦允侵?封裝、繼承和多態(tài)
封裝,顧名思義就是將內(nèi)容封裝到某個(gè)地方,以后再去調(diào)用被封裝在某處的內(nèi)容。
所以,在使用面向?qū)ο蟮姆庋b特性時(shí),需要:
1). 將內(nèi)容封裝到某處
2). 從某處調(diào)用被封裝的內(nèi)容
1). 通過對(duì)象直接調(diào)用被封裝的內(nèi)容: 對(duì)象.屬性名
2). 通過self間接調(diào)用被封裝的內(nèi)容: self.屬性名
3). 通過self間接調(diào)用被封裝的內(nèi)容:
self.方法名()
構(gòu)造方法init與其他普通方法不同的地方在于,當(dāng)一個(gè)對(duì)象被創(chuàng)建后,會(huì)立即調(diào)
用構(gòu)造方法。自動(dòng)執(zhí)行構(gòu)造方法里面的內(nèi)容。
對(duì)于面向?qū)ο蟮姆庋b來說,其實(shí)就是使用構(gòu)造方法將內(nèi)容封裝到 對(duì)象 中,然后通過
對(duì)象直接或者self間接獲取被封裝的內(nèi)容
class Student:
def __init__(self, name, score1, score2):
# 將對(duì)象和屬性封裝在一起
self.name = name
self.score1 = score1
self.score2 = score2
#print("self.name: ", self.name)
def compute_sum_score(self):
#獲取封裝的屬性信息方法一: , 通過對(duì)象名.屬性名的方式獲取。
return self.score1 + self.score2
stu1 = Student(name="張三", score1=100, score2=100)
#獲取封裝的屬性信息方法二: , 通過對(duì)象名.屬性名的方式獲取。
print("學(xué)生姓名: ", stu1.name)
sum_scores = stu1.compute_sum_score()
print("總分?jǐn)?shù): ", sum_scores)
創(chuàng)建一個(gè)類People,擁有的屬性為姓名, 性別和年齡, 擁有的方法為購(gòu)物,玩游戲,學(xué)習(xí);實(shí)例化
對(duì)象,執(zhí)行相應(yīng)的方法。 顯示如下:
小明,18歲,男,去西安賽格購(gòu)物廣場(chǎng)購(gòu)物
小王,22歲,男,去西安賽格購(gòu)物廣場(chǎng)購(gòu)物
小紅,10歲,女,在西部開源學(xué)習(xí)
class People:
print("正在創(chuàng)建類對(duì)象..........")
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def shopping(self):
print("%s,%d歲,%s,去西安賽格購(gòu)物廣場(chǎng)購(gòu)物" %(self.name, self.age, self.gender))
def playGame(self):
pass
def learning(self):
pass
#當(dāng)定義類的時(shí)候, 類內(nèi)容是否會(huì)執(zhí)行? 會(huì)執(zhí)行
#stu1 = People('xx', 10, 'xxx')"""
繼承特性
面向?qū)ο蟮娜筇匦允侵?封裝、繼承和多態(tài)
問題一: 如何讓實(shí)現(xiàn)繼承?
子類在繼承的時(shí)候,在定義類時(shí),小括號(hào)()中為父類的名字
問題二: 繼承的工作機(jī)制是什么?
父類的屬性、方法,會(huì)被繼承給子類。
舉例如下:
如果子類沒有定義__init__方法,父類有,那么在子類繼承父類的時(shí)候這個(gè)方法就被繼承了,
所以只要?jiǎng)?chuàng)建對(duì)象,就默認(rèn)執(zhí)行了那個(gè)繼承過來的__init__方法
#在Python代碼中,沒有指定父類, 默認(rèn)繼承object類。
#父類: object 子類: Student
class Student(object):
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print("%s正在學(xué)習(xí)編程......." %(self.name))
#父類: Student 子類: MathStudent
class MathStudent(Student):
# 重寫父類的learn方法
#重寫父類方法: 就是子類中,有一個(gè)和父類相同名字的方法,在子類中的方法會(huì)覆蓋掉父類中同名的方法。
def learn(self):
# 方法一: 調(diào)用父類的方法
#Student.learn(self)
#方法二: 調(diào)用父類的方法, 自動(dòng)幫當(dāng)前類尋找父類的名稱
super(MathStudent, self).learn()
print("%s正在學(xué)習(xí)英語四級(jí)....." %(self.name))
#父類: Student 子類: EnglishStudent
class EnglishStudent(Student):
pass
s1 = Student("粉條", 10, 'male')
print(s1.name)
#當(dāng)實(shí)例化對(duì)象, 子類沒有構(gòu)造方法, 自動(dòng)調(diào)用并執(zhí)行父類的構(gòu)造方法。
s2 = MathStudent("拉格朗日", 100, 'male')
#當(dāng)子類調(diào)用的方法沒有的時(shí)候, 自動(dòng)去父類里面尋找并執(zhí)行。
s2.learn()
問題一: 如何讓實(shí)現(xiàn)繼承?
子類在繼承的時(shí)候,在定義類時(shí),小括號(hào)()中為父類的名字
問題二: 繼承的工作機(jī)制是什么?
父類的屬性、方法,會(huì)被繼承給子類。
舉例如下:
如果子類沒有定義__init__方法,父類有,那么在子類繼承父類的時(shí)候這個(gè)方法就被繼承了,
所以只要?jiǎng)?chuàng)建對(duì)象,就默認(rèn)執(zhí)行了那個(gè)繼承過來的__init__方法。
#在Python代碼中,沒有指定父類, 默認(rèn)繼承object類。
#父類: object 子類: Student
class Student(object):
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
def learn(self):
print("%s正在學(xué)習(xí)編程......." %(self.name))
#父類: Student 子類: MathStudent
class MathStudent(Student):
pass
#父類: Student 子類: EnglishStudent
class EnglishStudent(Student):
pass
s1 = Student("粉條", 10, 'male')
print(s1.name)
#當(dāng)實(shí)例化對(duì)象, 子類沒有構(gòu)造方法, 自動(dòng)調(diào)用并執(zhí)行父類的構(gòu)造方法。
s2 = MathStudent("拉格朗日", 100, 'male')
#當(dāng)子類調(diào)用的方法沒有的時(shí)候, 自動(dòng)去父類里面尋找并執(zhí)行。
s2.learn()
默認(rèn)情況下,屬性在 Python 中都是“public”, 大多數(shù) OO 語言提供“訪問控
制符”來限定成員函數(shù)的訪問。
在 Python 中,實(shí)例的變量名如果以 開頭,就變成了一個(gè)私有變量/屬性
(private),實(shí)例的函數(shù)名如果以開頭,就變成了一個(gè)私有函數(shù)/方法(private)只
有內(nèi)部可以訪問,外部不能訪問。
#私有屬性和私有方法:
class Student(object):
需求: 學(xué)生成績(jī)保密, 外部不可以訪問分?jǐn)?shù), 只可以訪問分?jǐn)?shù)的等級(jí)
def __init__(self, name, age, score):
self.name = name
self.age = age
#self.__score是私有屬性, 只能在類的內(nèi)部訪問, 類的外部不可以訪問。
self.__score = score
#__get_level是私有方法,只能在類的內(nèi)部訪問, 類的外部不可以訪問。
def __get_level(self):
if 90 <= self.__score <= 100:
return "優(yōu)秀"
elif 80 <= self.__score < 90:
return "良好"
elif 60 <= self.__score < 80:
return "及格"
else:
return "不及格"
stu1 = Student("粉條", 10, 59)
#print(stu1.__score) # 調(diào)用私有屬性失敗
#print("學(xué)生分?jǐn)?shù)的等級(jí): ", stu1.__get_level()) # 調(diào)用私有方法失敗
#Python解釋器自動(dòng)將私有屬性和私有方法重命名了, 命名方式一般是_類名__屬性名、_類名__方法名
print(stu1._Student__score)
print(stu1._Student__get_level())
在Python 2及以前的版本中,由任意內(nèi)置類型派生出的類,都屬于“新式
類”,都會(huì)獲得所有“新式類”的特性;反之,即不由任意內(nèi)置類型派生出的類,
則稱之為“經(jīng)典類
“新式類”和“經(jīng)典類”的區(qū)分在Python 3之后就已經(jīng)不存在,在Python 3.x
之后的版本,因?yàn)樗械念惗寂缮詢?nèi)置類型object(即使沒有顯示的繼承
object類型),即所有的類都是“新式類”。
最明顯的區(qū)別在于繼承搜索的順序不同,即:
經(jīng)典類多繼承搜索順序(深度優(yōu)先算法):先深入繼承樹左側(cè)查找,然后再返回,開始查找右側(cè)。
新式類多繼承搜索順序(廣度優(yōu)先算法):先在水平方向查找,然后再向上查找,
class TeacherMajor(object):
def __init__(self, students_count):
self.student_count = students_count
class DoctorMajor(object):
def __init__(self, patients_count):
self.patients_count = patients_count
#子類Student擁有2個(gè)父類TeacherMajor和DoctorMajor
class Student(TeacherMajor, DoctorMajor):
def __init__(self, name, students_count, patients_count):
self.name = name
TeacherMajor.__init__(self, students_count)
DoctorMajor.__init__(self, patients_count)
##繼承的順序如何查看?
#print(Student.__mro__)
stu1 = Student("粉條", 0, 0)
print(stu1.patients_count)
print(stu1.student_count)
#coding:utf-8
#注意: Python2環(huán)境中做實(shí)驗(yàn)
#類D新式類.
class D(object):
def hello(self):
print("D...... hello")
class C(D):
def hello(self):
print("C...... hello")
class B(D):
pass
class A(B, C):
pass
#新式類多繼承搜索順序(廣度優(yōu)先算法):先在水平方向查找,然后再向上查找,
a = A()
a.hello()
#C...... hello
#coding:utf-8
#注意: Python2環(huán)境中做實(shí)驗(yàn)
#類D經(jīng)典類.
class D:
def hello(self):
print("D...... hello")
class C(D):
def hello(self):
print("C...... hello")
class B(D):
pass
class A(B, C):
pass
#經(jīng)典類多繼承搜索順序(深度優(yōu)先算法):先深入繼承樹左側(cè)查找,然后再返回,開始查找右側(cè)。
a = A()
a.hello()
#D...... hello
多態(tài)特性
多態(tài)的好處就是,當(dāng)我們需要傳入更多的子類,只需要繼承父類就可以了,而方法既可以直接
不重寫(即使用父類的),也可以重寫一個(gè)特有的。這就是多態(tài)的意思。調(diào)用方只管調(diào)用,不管
細(xì)節(jié),而當(dāng)我們新增一種的子類時(shí),只要確保新方法編寫正確,而不用管原來的代碼。這就是著
名的“開閉”原則:
對(duì)擴(kuò)展開放(Open for extension):允許子類重寫方法函數(shù)
對(duì)修改封閉(Closed for modification):不重寫,直接繼承父類方法函數(shù)
棧的封裝
棧是限制在一端進(jìn)行插入操作和刪除操作的線性表(俗稱堆棧),允許進(jìn)行操作的一端稱為“棧頂”,
另一固定端稱為“棧底”,當(dāng)棧中沒有元素時(shí)稱為“空棧”。向一個(gè)棧內(nèi)插入元素稱為是進(jìn)棧,push;
從一個(gè)棧刪除元素稱為是出棧,pop。特點(diǎn) :后進(jìn)先出(LIFO)。
隊(duì)列的封裝
隊(duì)列是限制在一端進(jìn)行插入操作和另一端刪除操作的線性表,允許進(jìn)行插入操作的一端稱為“隊(duì)尾”,
允許進(jìn)行刪除操作的一端稱為“隊(duì)頭”,,當(dāng)隊(duì)列中沒有元素時(shí)稱為“空隊(duì)”。特點(diǎn) :先進(jìn)先出(FIFO)
class Stack(object):
"""
根據(jù)列表的數(shù)據(jù)結(jié)構(gòu)封裝棧的數(shù)據(jù)結(jié)構(gòu)
屬性: 棧元素stack
方法:
get_top()
get_bootom()
push()
pop()
"""
def __init__(self):
self.stack = [] # [1, 2, 3]
def top(self):
return self.stack[-1]
def bootom(self):
return self.stack[0]
def push(self, item):
"""
:param item: 入棧元素
:return:
"""
self.stack.append(item)
return True
def pop(self):
item = self.stack.pop()
return item
def show(self):
return self.stack
#魔術(shù)方法, 使得代碼運(yùn)行更加簡(jiǎn)潔
def __len__(self):
return len(self.stack)
if __name__ == '__main__':
stack = Stack()
print(stack.show())
#print(stack.top())
#stack.push(1)
#stack.push(2)
#stack.push(3)
#print("入棧后: ", stack.show())
#item = stack.pop()
#print("出棧元素為: ", item)
#print("出棧后: ", stack.show())
#print('棧元素個(gè)數(shù): ', stack.__len__())
print('棧元素個(gè)數(shù): ', len(stack))
class Node(object):
def __init__(self, data, lchild=None, rchild=None):
self.data = data
self.lchild = lchild
self.rchild = rchild
#魔術(shù)方法: len(), __len__. str(), __str__
def __str__(self): # 友好的字符串顯示信息
return 'Node<%s>' % (self.data)
def pre_view( root):
"""
先序遍歷: 根節(jié)點(diǎn)-左子樹節(jié)點(diǎn)-右子樹節(jié)點(diǎn)
傳遞根節(jié)點(diǎn)
:param root:
:return:
"""
if root == None:
return
print(root.data)
pre_view(root.lchild)
pre_view(root.rchild)
def last_view(root):
"""
后序遍歷: -左子樹節(jié)點(diǎn)-右子樹節(jié)點(diǎn)-根節(jié)點(diǎn)
傳遞根節(jié)點(diǎn)
:param root:
:return:
"""
if root == None:
return
last_view(root.lchild)
last_view(root.rchild)
print(root.data)
def mid_view(root):
"""
中序遍歷: -左子樹節(jié)點(diǎn)--根節(jié)點(diǎn)-右子樹節(jié)點(diǎn)
傳遞根節(jié)點(diǎn)
:param root:
:return:
"""
if root == None:
return
mid_view(root.lchild)
print(root.data)
mid_view(root.rchild)
if __name__ == '__main__':
D = Node('D')
B = Node('B', D)
C = Node('C')
A = Node('A', B, C)
#print("A-left: ", str(A.lchild))
#print("A-right: ", str(A.rchild))
#先序遍歷(根左右)、中序遍歷(左根右)、后序遍歷(左右根)
print("先序遍歷:")
pre_view(A)
print("后序遍歷:")
last_view(A)
print("中序遍歷:")
mid_view(A)