Python基础知识(第七天)
90.嵌套函數(shù)_內(nèi)部函數(shù)_數(shù)據(jù)隱藏
嵌套函數(shù)
在函數(shù)內(nèi)部定義的函數(shù)!
?一般在什么情況下使用嵌套函數(shù)?
1.封裝 - 數(shù)據(jù)隱藏
? ? ? ?外部無(wú)法訪問(wèn)“嵌套函數(shù)”。
2.貫徹?DRY(Don’t Repeat Yourself)原則
? ? ? ?嵌套函數(shù),可以讓我們?cè)诤瘮?shù)內(nèi)部避免重復(fù)代碼。
3.閉包
? ? ? ?后面會(huì)詳細(xì)講解。
91.nonlocal_global
nonlocal 關(guān)鍵字
nonlocal 用來(lái)聲明外層的局部變量。
global 用來(lái)聲明全局變量。
a = 100 def outer():b = 10def inner():nonlocal b #聲明外部函數(shù)的局部變量print("inner b:",b)b = 20global a #聲明全局變量a = 1000inner() print("outer b:",b) outer() print("a:",a)inner b:? 10
outer b:? 20
a:? ? 1000
92.LEGB規(guī)則
Python 在查找“名稱(chēng)”時(shí),是按照LEGB 規(guī)則查找的:Local-->Enclosed-->Global-->Built
Local 指的就是函數(shù)或者類(lèi)的方法內(nèi)部
Enclosed 指的是嵌套函數(shù)(一個(gè)函數(shù)包裹另一個(gè)函數(shù),閉包)
Global 指的是模塊中的全局變量
Built?in 指的是Python?為自己保留的特殊名稱(chēng)。
如果某個(gè)name?映射在局部(local)命名空間中沒(méi)有找到,接下來(lái)就會(huì)在閉包作用域(enclosed)進(jìn)行搜索,如果閉包作用域也沒(méi)有找到,Python?就會(huì)到全局(global)命名空間中進(jìn)行查找,最后會(huì)在內(nèi)建(built-in)命名空間搜索(如果一個(gè)名稱(chēng)在所有命名空間中都沒(méi)有找到就會(huì)產(chǎn)生一個(gè)NameError)
93.面向?qū)ο蠛兔嫦蜻^(guò)程的區(qū)別_執(zhí)行者思維_設(shè)計(jì)者思維
面向?qū)ο?#xff08;Object oriented Programming,OOP)編程的思想主要是針對(duì)大型軟件設(shè)計(jì)而來(lái)的。面向?qū)ο缶幊淌钩绦虻臄U(kuò)展性更強(qiáng)、可讀性更好,使的編程可以像搭積木一樣簡(jiǎn)單。
面向?qū)ο缶幊虒?shù)據(jù)和操作數(shù)據(jù)相關(guān)的方法封裝到對(duì)象中,組織代碼和數(shù)據(jù)的方式更加接近人的思維,從而大大提高了編程的效率。
Python完全采用了面向?qū)ο蟮乃枷?#xff0c;是真正面向?qū)ο蟮木幊陶Z(yǔ)言,完全支持面向?qū)ο蟮幕竟δ?#xff0c;例如:繼承、多態(tài)、封裝等。Python 中,一切皆對(duì)象。我們?cè)谇懊鎸W(xué)習(xí)的數(shù)據(jù)類(lèi)型、函數(shù)等,都是對(duì)象。
面向?qū)ο蠛兔嫦蜻^(guò)程區(qū)別
面向過(guò)程(Procedure?Oriented)思維
面向過(guò)程編程更加關(guān)注的是“程序的邏輯流程”,是一種“執(zhí)行者”思維,適合編寫(xiě)小規(guī)模的程序。
面向過(guò)程適合簡(jiǎn)單、不需要協(xié)作的事務(wù)。但是當(dāng)我們思考比較復(fù)雜的問(wèn)題,比如“如何造車(chē)?”,就會(huì)發(fā)現(xiàn)列出 1234?這樣的步驟,是不可能的。那是因?yàn)?#xff0c;造車(chē)太復(fù)雜,需要很多協(xié)作才能完成。此時(shí)面向?qū)ο笏枷刖蛻?yīng)運(yùn)而生了。
面向?qū)ο?Object?Oriented)思維
面向?qū)ο?Object)思想更契合人的思維模式。我們首先思考的是“怎么設(shè)計(jì)這個(gè)事物?” ???比如思考造車(chē),我們就會(huì)先思考“車(chē)怎么設(shè)計(jì)?”,而不是“怎么按步驟造車(chē)的問(wèn)題”。這就是思維方式的轉(zhuǎn)變。
為了便于協(xié)作,我們找輪胎廠完成制造輪胎的步驟,發(fā)動(dòng)機(jī)廠完成制造發(fā)動(dòng)機(jī)的步驟,這樣,發(fā)現(xiàn)大家可以同時(shí)進(jìn)行車(chē)的制造,最終進(jìn)行組裝,大大提高了效率。但是,具體到輪胎廠的一個(gè)流水線操作,仍然是有步驟的,還是離不開(kāi)面向過(guò)程思想!
我們千萬(wàn)不要把面向過(guò)程和面向?qū)ο髮?duì)立起來(lái)。他們是相輔相成的。面向?qū)ο箅x不開(kāi)面向過(guò)程!
面向?qū)ο笏伎挤绞?/strong>
遇到復(fù)雜問(wèn)題,先從問(wèn)題中找名詞(面向過(guò)程更多的是找動(dòng)詞),然后確立這些名詞哪 ???些可以作為類(lèi),再根據(jù)問(wèn)題需求確定的類(lèi)的屬性和方法,確定類(lèi)之間的關(guān)系。
94.對(duì)象的進(jìn)化故事
對(duì)象的進(jìn)化
隨著編程面臨的問(wèn)題越來(lái)越復(fù)雜,編程語(yǔ)言本身也在進(jìn)化,從主要處理簡(jiǎn)單數(shù)據(jù)開(kāi)始,隨著數(shù)據(jù)變多進(jìn)化“數(shù)組”; 數(shù)據(jù)類(lèi)型變復(fù)雜,進(jìn)化出了“結(jié)構(gòu)體”; 處理數(shù)據(jù)的方式和邏輯變復(fù)雜,進(jìn)化出了“對(duì)象”。
1.簡(jiǎn)單數(shù)據(jù)
像 30,40,50.4 等這些數(shù)字,可以看做是簡(jiǎn)單數(shù)據(jù)。最初的計(jì)算機(jī)編程,都是像這樣的數(shù)字。
2.數(shù)組
將同類(lèi)型的數(shù)據(jù)放到一起。比如:整數(shù)數(shù)組[20,30,40],浮點(diǎn)數(shù)數(shù)組[10.2, 11.3, 12.4], 字符串?dāng)?shù)組:[“aa”,”bb”,”cc”]
3.結(jié)構(gòu)體
將不同類(lèi)型的數(shù)據(jù)放到一起,是 C 語(yǔ)言中的數(shù)據(jù)結(jié)構(gòu)。比如:
struct resume{
? ? int age;
? ? char?name[10];
? ? double?salary;
?};
4.對(duì)象
將不同類(lèi)型的數(shù)據(jù)、方法(即函數(shù))放到一起,就是對(duì)象。
95.類(lèi)的定義_類(lèi)和對(duì)象的關(guān)系
類(lèi)的定義
我們把對(duì)象比作一個(gè)“餅干”,類(lèi)就是制造這個(gè)餅干的“模具”。
我們通過(guò)類(lèi)定義數(shù)據(jù)類(lèi)型的屬性(數(shù)據(jù))和方法(行為),也就是說(shuō),“類(lèi)將行為和狀態(tài)打包在一起”。
??從一個(gè)類(lèi)創(chuàng)建對(duì)象時(shí),每個(gè)對(duì)象會(huì)共享這個(gè)類(lèi)的行為(類(lèi)中定義的方法),但會(huì)有自己的屬性值(不共享狀態(tài))。更具體一點(diǎn):“方法代碼是共享的,屬性數(shù)據(jù)不共享”。
Python 中,“一切皆對(duì)象”。類(lèi)也稱(chēng)為“類(lèi)對(duì)象”,類(lèi)的實(shí)例也稱(chēng)為“實(shí)例對(duì)象”。
定義類(lèi)的語(yǔ)法格式如下:
class 類(lèi)名:
? ? ? 類(lèi)體
要點(diǎn)如下:
1.類(lèi)名必須符合“標(biāo)識(shí)符”的規(guī)則;一般規(guī)定,首字母大寫(xiě),多個(gè)單詞使用“駝峰原則”。
2.類(lèi)體中我們可以定義屬性和方法。
3.屬性用來(lái)描述數(shù)據(jù),方法(即函數(shù))用來(lái)描述這些數(shù)據(jù)相關(guān)的操作。?
class Student: # 類(lèi)名一般首字母大寫(xiě),多個(gè)單詞采用駝峰原則def __init__(self, name, score): # 構(gòu)造方法第一個(gè)參數(shù)必須為 selfself.score = scoreself.name = namedef say_score(self):print("{0}的分?jǐn)?shù)是:{1}".format(self.name, self.score))s1 = Student("高崎", 18) s1.say_score()96.構(gòu)造函數(shù)__init__
? init? 構(gòu)造方法和? new? 方法
類(lèi)是抽象的,也稱(chēng)之為“對(duì)象的模板”。我們需要通過(guò)類(lèi)這個(gè)模板,創(chuàng)建類(lèi)的實(shí)例對(duì)象,然后才能使用類(lèi)定義的功能。
我們前面說(shuō)過(guò)一個(gè) Python?對(duì)象包含三個(gè)部分:id(identity?識(shí)別碼)、type(對(duì)象類(lèi)型)、value(對(duì)象的值)。
現(xiàn)在,我們可以更進(jìn)一步的說(shuō),一個(gè) Python 對(duì)象包含如下部分:
1.id(identity?識(shí)別碼)
2.type(對(duì)象類(lèi)型)
3.value(對(duì)象的值) ?1)方法(method)? ? 2)屬性(attribute)
????init?()的要點(diǎn)如下:
1.名稱(chēng)固定,必須為: init ()
2.第一個(gè)參數(shù)固定,必須為:self。self?指的就是剛剛創(chuàng)建好的實(shí)例對(duì)象。
3.構(gòu)造函數(shù)通常用來(lái)初始化實(shí)例對(duì)象的實(shí)例屬性,如下代碼就是初始化實(shí)例屬性:name ???和 score。
def __init__(self, name, score): # 構(gòu)造方法第一個(gè)參數(shù)必須為 selfself.score = scoreself.name = name?4.通過(guò)“類(lèi)名(參數(shù)列表)”來(lái)調(diào)用構(gòu)造函數(shù)。調(diào)用后,將創(chuàng)建好的對(duì)象返回給相應(yīng)的變量。 ???比如:s1 = Student('張三', 80)
5.????init ()方法:初始化創(chuàng)建好的對(duì)象,初始化指的是:“給實(shí)例屬性賦值”
6.????new__()方法: 用于創(chuàng)建對(duì)象,但我們一般無(wú)需重定義該方法。
7.如果我們不定義?init 方法,系統(tǒng)會(huì)提供一個(gè)默認(rèn)的??init??方法。如果我們定義了帶參的?init 方法,系統(tǒng)不創(chuàng)建默認(rèn)的??init 方法。
97.實(shí)例屬性_內(nèi)存分析
實(shí)例屬性
實(shí)例屬性是從屬于實(shí)例對(duì)象的屬性,也稱(chēng)為“實(shí)例變量”。他的使用有如下幾個(gè)要點(diǎn):
1.實(shí)例屬性一般在?init ()方法中通過(guò)如下代碼定義: self.實(shí)例屬性名 = 初始值
2.在本類(lèi)的其他實(shí)例方法中,也是通過(guò) self?進(jìn)行訪問(wèn): self.實(shí)例屬性名
3.創(chuàng)建實(shí)例對(duì)象后,通過(guò)實(shí)例對(duì)象訪問(wèn):
obj01 =?類(lèi) 名()? ? ? ? ? ? ? ? #創(chuàng)建對(duì)象,調(diào)用??init?()初始化屬性
obj01.實(shí)例屬性名?=?值? ? ? ? ? ? ? #可以給已有屬性賦值,也可以新加屬性
98.實(shí)例方法_內(nèi)存分析方法調(diào)用過(guò)程_dir()_isinstance
實(shí)例方法
實(shí)例方法是從屬于實(shí)例對(duì)象的方法。實(shí)例方法的定義格式如下:
def 方法名(self?[,?形參列表]):
? ? ? ? ? 函數(shù)體
方法的調(diào)用格式如下:
? ? ? ? ? ?對(duì)象.方法名([實(shí)參列表])
要點(diǎn):
1.定義實(shí)例方法時(shí),第一個(gè)參數(shù)必須為 self。和前面一樣,self?指當(dāng)前的實(shí)例對(duì)象。
2.調(diào)用實(shí)例方法時(shí),不需要也不能給 self?傳參。self?由解釋器自動(dòng)傳參
函數(shù)和方法的區(qū)別
1.都是用來(lái)完成一個(gè)功能的語(yǔ)句塊,本質(zhì)一樣。
2.方法調(diào)用時(shí),通過(guò)對(duì)象來(lái)調(diào)用。方法從屬于特定實(shí)例對(duì)象,普通函數(shù)沒(méi)有這個(gè)特點(diǎn)。
3.直觀上看方法定義時(shí)需要傳遞 self,函數(shù)不需要。?
?其他操作:
1.dir(obj)可以獲得對(duì)象的所有屬性、方法
2.obj.? ???dict__ 對(duì)象的屬性字典
3.pass?空語(yǔ)句
4.isinstance(對(duì)象,類(lèi)型) 判斷“對(duì)象”是不是“指定類(lèi)型”
99.類(lèi)對(duì)象
類(lèi)對(duì)象
我們?cè)谇懊嬷v的類(lèi)定義格式中,“class類(lèi)名:”。實(shí)際上,當(dāng)解釋器執(zhí)行?class?語(yǔ)句時(shí), 就會(huì)創(chuàng)建一個(gè)類(lèi)對(duì)象。
?我們可以看到實(shí)際上生成了一個(gè)變量名就是類(lèi)名“Student”的對(duì)象。我們通過(guò)賦值給新變量 Stu2,也能實(shí)現(xiàn)相關(guān)的調(diào)用。說(shuō)明,確實(shí)創(chuàng)建了“類(lèi)對(duì)象”。
100.類(lèi)屬性_內(nèi)存分析創(chuàng)建類(lèi)和對(duì)象的底層
類(lèi)屬性
類(lèi)屬性是從屬于“類(lèi)對(duì)象”的屬性,也稱(chēng)為“類(lèi)變量”。由于,類(lèi)屬性從屬于類(lèi)對(duì)象,可以被所有實(shí)例對(duì)象共享。
類(lèi)屬性的定義方式:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? class 類(lèi)名:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 類(lèi)變量名= 初始值
在類(lèi)中或者類(lèi)的外面,我們可以通過(guò):“類(lèi)名.類(lèi)變量名”來(lái)讀寫(xiě)。
class Student:company = "SXT" #類(lèi)屬性count = 0 #類(lèi)屬性def __init__(self,name,score):self.name = name #實(shí)例屬性self.score = scoreself.score = scoreStudent.count = Student.count+1def say_score(self): #實(shí)例方法print("我的公司是:",Student.company)print(self.name,'的分?jǐn)?shù)是:',self.score)s1 = Student('張三',80) s1.say_score() print('一共創(chuàng)建{0}個(gè) Student 對(duì)象'.format(Student.count))101.類(lèi)方法_靜態(tài)方法_內(nèi)存分析圖示
類(lèi)方法
類(lèi)方法是從屬于“類(lèi)對(duì)象”的方法。類(lèi)方法通過(guò)裝飾器@classmethod 來(lái)定義,格式如下:
@classmethod
def 類(lèi)方法名(cls [,形參列
表])?: 函數(shù)體
要點(diǎn)如下:
1.@classmethod?必須位于方法上面一行
2.第一個(gè) cls?必須有;cls?指的就是“類(lèi)對(duì)象”本身;
3.調(diào)用類(lèi)方法格式:“類(lèi)名.類(lèi)方法名(參數(shù)列表)”。 參數(shù)列表中,不需要也不能給 cls?傳值。
4.類(lèi)方法中訪問(wèn)實(shí)例屬性和實(shí)例方法會(huì)導(dǎo)致錯(cuò)誤
5.子類(lèi)繼承父類(lèi)方法時(shí),傳入 cls?是子類(lèi)對(duì)象,而非父類(lèi)對(duì)象
class Student:company = "SXT"@classmethoddef printCompany(cls): print(cls.company)Student.printCompany()靜態(tài)方法
Python 中允許定義與“類(lèi)對(duì)象”無(wú)關(guān)的方法,稱(chēng)為“靜態(tài)方法”。
“靜態(tài)方法”和在模塊中定義普通函數(shù)沒(méi)有區(qū)別,只不過(guò)“靜態(tài)方法”放到了“類(lèi)的名字空間里面”,需要通過(guò)“類(lèi)調(diào)用”。
靜態(tài)方法通過(guò)裝飾器@staticmethod 來(lái)定義,格式如下:
? ? ? ? ? ? ? ? ? ? ?@staticmethod
? ? ? ? ? ? ? ? ? ? ?def 靜態(tài)方法名([形參列表]) :
? ? ? ? ? ? ? ? ? ? ? ? ? 函數(shù)體
要點(diǎn)如下:
1.@staticmethod?必須位于方法上面一行
2.調(diào)用靜態(tài)方法格式:“類(lèi)名.靜態(tài)方法名(參數(shù)列表)”。
3.靜態(tài)方法中訪問(wèn)實(shí)例屬性和實(shí)例方法會(huì)導(dǎo)致錯(cuò)誤
class Student:company = "SXT" #類(lèi)屬性@staticmethoddef add(a, b): #靜態(tài)方法print("{0}+{1}={2}".format(a,b,(a+b)))return a+bStudent.add(20,30)靜態(tài)方法、類(lèi)方法不能實(shí)例變量和實(shí)例方法。
102.__del__()析構(gòu)方法和垃圾回收機(jī)制
????del????方法稱(chēng)為“析構(gòu)方法”,用于實(shí)現(xiàn)對(duì)象被銷(xiāo)毀時(shí)所需的操作。比如:釋放對(duì)象占用的資源,例如:打開(kāi)的文件資源、網(wǎng)絡(luò)連接等。Python 實(shí)現(xiàn)自動(dòng)的垃圾回收,當(dāng)對(duì)象沒(méi)有被引用時(shí)(引用計(jì)數(shù)為0),由垃圾回收器調(diào)用????del????方法。
我們也可以通過(guò) del?語(yǔ)句刪除對(duì)象,從而保證調(diào)用?del?方法。系統(tǒng)會(huì)自動(dòng)提供?del?方法,一般不需要自定義析構(gòu)方法。
class Person:def __del__ (self):print("銷(xiāo)毀對(duì)象:{0}".format(self)) p1 = Person() p2 = Person() del p2 print("程序結(jié)束")銷(xiāo)毀對(duì)象:<?main__.Person object at 0x02175610>
程序結(jié)束
銷(xiāo)毀對(duì)象:<?main__.Person object at 0x021755D0>
103.__call__()方法和可調(diào)用對(duì)象
定義了__call__方法的對(duì)象,稱(chēng)為“可調(diào)用對(duì)象”,即該對(duì)象可以像函數(shù)一樣被調(diào)用。
class SalaryAccount:def __call__(self, salary):yearSalary = salary*12 daySalary = salary//30return dict(yearSalary=yearSalary,daySalary=daySalary)s = SalaryAccount() print(s(30000))總結(jié)
以上是生活随笔為你收集整理的Python基础知识(第七天)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Python基础知识(第六天)
- 下一篇: websocket python爬虫_p