類和對(duì)象
創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比中牟網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式中牟網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋中牟地區(qū)。費(fèi)用合理售后完善,10余年實(shí)體公司更值得信賴。
對(duì)象是什么?
對(duì)象=屬性(靜態(tài))+方法(動(dòng)態(tài));
屬性一般是一個(gè)個(gè)變量;方法是一個(gè)個(gè)函數(shù);
#類的屬性 就是 類變量
#實(shí)例變量:定義在方法中的變量,只作用于當(dāng)前實(shí)例的類。
例子:
class Turtle:#python 中類名約定以大寫字母開頭
'''關(guān)于類的簡(jiǎn)單例子。。。'''
#屬性 == 類變量
color ="green"
weight="10kg"
legs=4
shell=True
mouth='big'
#方法
def climb(self):
self.name = "test" #實(shí)例變量:定義在方法中的變量,只作用于當(dāng)前實(shí)例的類。
print("我在很努力爬。")
def run(self):
print('我在很努力跑。')
def bite(self):
print('我要要要要要')
def sleep(self):
print('我要睡覺啦。')
#創(chuàng)建一個(gè)實(shí)例對(duì)象也就是類的實(shí)例化!
tt =Turtle() #類的實(shí)例化,也就是創(chuàng)建一個(gè)對(duì)象,類名約定大寫字母開頭
tt.bite() #創(chuàng)建好類后就能調(diào)用類里面的方法叻;
tt.sleep()
9.3.2. 類對(duì)象
類對(duì)象支持兩種操作:屬性引用和實(shí)例化。
屬性引用 使用和 Python 中所有的屬性引用一樣的標(biāo)準(zhǔn)語法:obj.name。類對(duì)象創(chuàng)建后,類命名空間中所有的命名都是有效屬性名。所以如果類定義是這樣:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
那么 MyClass.i 和 MyClass.f 是有效的屬性引用,分別返回一個(gè)整數(shù)和一個(gè)方法對(duì)象。也可以對(duì)類屬性賦值,你可以通過給 MyClass.i 賦值來修改它。 __doc__ 也是一個(gè)有效的屬性,返回類的文檔字符串:"A simple example class"。
類的 實(shí)例化 使用函數(shù)符號(hào)。只要將類對(duì)象看作是一個(gè)返回新的類實(shí)例的無參數(shù)函數(shù)即可。例如(假設(shè)沿用前面的類):
x = MyClass()
以上創(chuàng)建了一個(gè)新的類 實(shí)例 并將該對(duì)象賦給局部變量 x。
這個(gè)實(shí)例化操作(“調(diào)用”一個(gè)類對(duì)象)來創(chuàng)建一個(gè)空的對(duì)象。很多類都傾向于將對(duì)象創(chuàng)建為有初始狀態(tài)的。因此類可能會(huì)定義一個(gè)名為 __init__() 的特殊方法,像下面這樣:
def __init__(self):
self.data = []
類定義了 __init__() 方法的話,類的實(shí)例化操作會(huì)自動(dòng)為新創(chuàng)建的類實(shí)例調(diào)用 __init__() 方法。所以在下例中,可以這樣創(chuàng)建一個(gè)新的實(shí)例:
x = MyClass()
當(dāng)然,出于彈性的需要,__init__() 方法可以有參數(shù)。事實(shí)上,參數(shù)通過 __init__() 傳遞到類的實(shí)例化操作上。例如,
class Complex:
... def __init__(self, realpart, imagpart):
... self.r = realpart
... self.i = imagpart
...
x = Complex(3.0, -4.5)
x.r, x.i
(3.0, -4.5)
類,class,用來描述具有相同的屬性和方法的對(duì)象的集合。它定義了該集合中每個(gè)對(duì)象所共有的屬性和方法。對(duì)象是類的實(shí)例。
函數(shù),是組織好的,可重復(fù)使用的,用來實(shí)現(xiàn)單一,或相關(guān)聯(lián)功能的代碼段。
函數(shù)能提高應(yīng)用的模塊性,和代碼的重復(fù)利用率。你已經(jīng)知道python提供了許多內(nèi)建函數(shù),比如print()。但你也可以自己創(chuàng)建函數(shù),這被叫作用戶自定義函數(shù)。
python語言中類和函數(shù)的區(qū)別
1、規(guī)則不同
類是一種引用數(shù)據(jù)類型,類似于byte、short、int(char)、long、float、double等基本數(shù)據(jù)類型;
函數(shù)必須聲明后才可以被調(diào)用,調(diào)用格式為:函數(shù)名(實(shí)參)調(diào)用時(shí)函數(shù)名后的小括號(hào)中的實(shí)參必須和聲明函數(shù)時(shí)的函數(shù)括號(hào)中的形參個(gè)數(shù)相同。
2、主體不同
類是面向?qū)ο蟪绦蛟O(shè)計(jì)實(shí)現(xiàn)信息封裝的基礎(chǔ);
函數(shù)是指一段在一起的、可以做某一件事的子程序。
3、特點(diǎn)不同
類是一種用戶定義的引用數(shù)據(jù)類型,也稱類類型,每個(gè)類包含數(shù)據(jù)說明和一組操作數(shù)據(jù)或者傳遞消息的函數(shù),類的實(shí)例稱為對(duì)象;
函數(shù)分為全局函數(shù)、全局靜態(tài)函數(shù),在類中還可以定義構(gòu)造函數(shù)、析構(gòu)函數(shù)、拷貝構(gòu)造函數(shù)、成員函數(shù)、友元函數(shù)、運(yùn)算符重載函數(shù)、內(nèi)聯(lián)函數(shù)等。
Python中的變量也是對(duì)象,函數(shù)也是對(duì)象,類也是對(duì)象,Python中一切皆對(duì)象。
變量的概念
變量存儲(chǔ)在內(nèi)存中的值。這就意味著在創(chuàng)建變量時(shí)會(huì)在內(nèi)存中開辟一個(gè)空間。
基于變量的數(shù)據(jù)類型,解釋器會(huì)分配指定內(nèi)存,并決定什么數(shù)據(jù)可以被存儲(chǔ)在內(nèi)存中。
因此,變量可以指定不同的數(shù)據(jù)類型,這些變量可以存儲(chǔ)整數(shù),小數(shù)或字符。
變量賦值
Python 中的變量賦值不需要類型聲明。
每個(gè)變量在內(nèi)存中創(chuàng)建,都包括變量的標(biāo)識(shí),名稱和數(shù)據(jù)這些信息。
每個(gè)變量在使用前都必須賦值,變量賦值以后該變量才會(huì)被創(chuàng)建。
等號(hào)(=)用來給變量賦值。
等號(hào)(=)運(yùn)算符左邊是一個(gè)變量名,等號(hào)(=)運(yùn)算符右邊是存儲(chǔ)在變量中的值。
Python學(xué)習(xí)網(wǎng)- 專業(yè)的python自學(xué)、交流公益平臺(tái)!
眾所周知,Python是一門面向?qū)ο蟮恼Z言,在Python無論是數(shù)值、字符串、函數(shù)亦或是類型、類,都是對(duì)象。
對(duì)象是在 堆 上分配的結(jié)構(gòu),我們定義的所有變量、函數(shù)等,都存儲(chǔ)于堆內(nèi)存,而變量名、函數(shù)名則是一個(gè)存儲(chǔ)于 棧 中、指向堆中具體結(jié)構(gòu)的引用。
要想深入學(xué)習(xí)Python,首先需要知道Python對(duì)象的定義。
我們通常說的Python都是指CPython,底層由C語言實(shí)現(xiàn),源碼地址: cpython [GitHub]
Python對(duì)象的定義位于 Include/object.h ,是一個(gè)名為 PyObject 的結(jié)構(gòu)體:
Python中的所有對(duì)象都繼承自PyObejct,PyObject包含一個(gè)用于垃圾回收的雙向鏈表,一個(gè)引用計(jì)數(shù)變量 ob_refcnt 和 一個(gè)類型對(duì)象指針 ob_type
從PyObejct的注釋中,我們可以看到這樣一句:每個(gè)指向 可變大小Python對(duì)象 的指針也可以轉(zhuǎn)換為 PyVarObject* (可變大小的Python對(duì)象會(huì)在下文中解釋)。 PyVarObejct 就是在PyObject的基礎(chǔ)上多了一個(gè) ob_size 字段,用于存儲(chǔ)元素個(gè)數(shù):
在PyObject結(jié)構(gòu)中,還有一個(gè)類型對(duì)象指針 ob_type ,用于表示Python對(duì)象是什么類型,定義Python對(duì)象類型的是一個(gè) PyTypeObject 接口體
實(shí)際定義是位于 Include/cpython/object.h 的 _typeobject :
在這個(gè)類型對(duì)象中,不僅包含了對(duì)象的類型,還包含了如分配內(nèi)存大小、對(duì)象標(biāo)準(zhǔn)操作等信息,主要分為:
以Python中的 int類型 為例,int類型對(duì)象的定義如下:
從PyObject的定義中我們知道,每個(gè)對(duì)象的 ob_type 都要指向一個(gè)具體的類型對(duì)象,比如一個(gè)數(shù)值型對(duì)象 100 ,它的ob_type會(huì)指向 int類型對(duì)象PyLong_Type 。
PyTypeObject結(jié)構(gòu)體第一行是一個(gè)PyObject_VAR_HEAD宏,查看宏定義可知PyTypeObject是一個(gè)變長(zhǎng)對(duì)象
也就是說,歸根結(jié)底 類型對(duì)象也是一個(gè)對(duì)象 ,也有ob_type屬性,那 PyLong_Type 的 ob_type 是什么呢?
回到PyLong_Type的定義,第一行 PyVarObject_HEAD_INIT(PyType_Type, 0) ,查看對(duì)應(yīng)的宏定義
由以上關(guān)系可以知道, PyVarObject_HEAD_INIT(PyType_Type, 0) = { { _PyObject_EXTRA_INIT 1, PyType_Type } 0} ,將其代入 PyObject_VAR_HEAD ,得到一個(gè)變長(zhǎng)對(duì)象:
這樣看就很明確了,PyLong_Type的類型就是PyType_Typ,同理可知, Python類型對(duì)象的類型就是PyType_Type ,而 PyType_Type對(duì)象的類型是它本身
從上述內(nèi)容中,我們知道了對(duì)象和對(duì)象類型的定義,那么根據(jù)定義,對(duì)象可以有以下兩種分類
Python對(duì)象定義有 PyObject 和 PyVarObject ,因此,根據(jù)對(duì)象大小是否可變的區(qū)別,Python對(duì)象可以劃分為 可變對(duì)象(變長(zhǎng)對(duì)象) 和 不可變對(duì)象(定長(zhǎng)對(duì)象)
原本的對(duì)象a大小并沒有改變,只是s引用的對(duì)象改變了。這里的對(duì)象a、對(duì)象b就是定長(zhǎng)對(duì)象
可以看到,變量l仍然指向?qū)ο骯,只是對(duì)象a的內(nèi)容發(fā)生了改變,數(shù)據(jù)量變大了。這里的對(duì)象a就是變長(zhǎng)對(duì)象
由于存在以上特性,所以使用這兩種對(duì)象還會(huì)帶來一種區(qū)別:
聲明 s2 = s ,修改s的值: s = 'new string' ,s2的值不會(huì)一起改變,因?yàn)橹皇莝指向了一個(gè)新的對(duì)象,s2指向的舊對(duì)象的值并沒有發(fā)生改變
聲明 l2 = l ,修改l的值: l.append(6) ,此時(shí)l2的值會(huì)一起改變,因?yàn)閘和l2指向的是同一個(gè)對(duì)象,而該對(duì)象的內(nèi)容被l修改了
此外,對(duì)于 字符串 對(duì)象,Python還有一套內(nèi)存復(fù)用機(jī)制,如果兩個(gè)字符串變量值相同,那它們將共用同一個(gè)對(duì)象:
對(duì)于 數(shù)值型 對(duì)象,Python會(huì)默認(rèn)創(chuàng)建0~2 8 以內(nèi)的整數(shù)對(duì)象,也就是 0 ~ 256 之間的數(shù)值對(duì)象是共用的:
按照Python數(shù)據(jù)類型,對(duì)象可分為以下幾類:
Python創(chuàng)建對(duì)象有兩種方式,泛型API和和類型相關(guān)的API
這類API通常以 PyObject_xxx 的形式命名,可以應(yīng)用在任意Python對(duì)象上,如:
使用 PyObjecg_New 創(chuàng)建一個(gè)數(shù)值型對(duì)象:
這類API通常只能作用于一種類型的對(duì)象上,如:
使用 PyLong_FromLong 創(chuàng)建一個(gè)數(shù)值型對(duì)象:
在我們使用Python聲明變量的時(shí)候,并不需要為變量指派類型,在給變量賦值的時(shí)候,可以賦值任意類型數(shù)據(jù),如:
從Python對(duì)象的定義我們已經(jīng)可以知曉造成這個(gè)特點(diǎn)的原因了,Python創(chuàng)建對(duì)象時(shí),會(huì)分配內(nèi)存進(jìn)行初始化,然后Python內(nèi)部通過 PyObject* 變量來維護(hù)這個(gè)對(duì)象,所以在Python內(nèi)部各函數(shù)直接傳遞的都是一種泛型指針 PyObject* ,這個(gè)指針?biāo)赶虻膶?duì)象類型是不固定的,只能通過所指對(duì)象的 ob_type 屬性動(dòng)態(tài)進(jìn)行判斷,而Python正是通過 ob_type 實(shí)現(xiàn)了多態(tài)機(jī)制
Python在管理維護(hù)對(duì)象時(shí),通過引用計(jì)數(shù)來判斷內(nèi)存中的對(duì)象是否需要被銷毀,Python中所有事物都是對(duì)象,所有對(duì)象都有引用計(jì)數(shù) ob_refcnt 。
當(dāng)一個(gè)對(duì)象的引用計(jì)數(shù)減少到0之后,Python將會(huì)釋放該對(duì)象所占用的內(nèi)存和系統(tǒng)資源。
但這并不意味著最終一定會(huì)釋放內(nèi)存空間,因?yàn)轭l繁申請(qǐng)釋放內(nèi)存會(huì)大大降低Python的執(zhí)行效率,因此Python中采用了內(nèi)存對(duì)象池的技術(shù),是的對(duì)象釋放的空間會(huì)還給內(nèi)存池,而不是直接釋放,后續(xù)需要申請(qǐng)空間時(shí),優(yōu)先從內(nèi)存對(duì)象池中獲取。