python自定義對象
1. python怎麼定義對象屬性
就比方說 有一個類 叫做 car 這個類的屬性 可以有 color size brand price year 等描述性的東西 這個類的方法 可以是 run stop forward backward 等執行性的東西 class car: #定義基本屬性 color = '' size = 0 brand = '' price = 0 year = 0 #...
2. python中類對象和方法的區別是什麼
python使用對象模型來存儲數據,也就是說構造任何類型的值都是一個對象。所有的python對象都擁有三個特性:身份id,類型和值。
身份id:唯一的身份標識,可以使用內建函數id()來得到,這個值可以被認為是該對象的內存地址。
類型:對象的類型決定了該對象可以保存什麼類型的值,可以進行什麼樣的操作,以及遵循什麼樣的規則,可以用內建函數type()查看
python對象的類型,也可以用isinstance(),在python中類型也是對象。
值:對象表示的數據項。布爾邏輯運算符包括and、or、not,對象值的比較除了一些常見的運算符(< > <= >= == !=)之外,還可以
使用cmp()內建函數,如果是用戶自定義對象,cmp()對調用該類的特殊方法__cmp__()。對於字元串來說,內建函數str(obj)返回對象適
合可讀性好的字元串表示,而另一個內建函數repr(obj)返回一個對象的字元串表示,通常情況下obj == eval(repr(obj))這個等式是成立
的。可以這么說,repr()的輸出對python比較友好,str()的輸出對人比較友好。方法是在類中定義的函數。
更多技術請關注Python視頻教程。
3. Python調用自定義模塊方法有什麼
import語句
自定義模塊可以採用import語句來進行引入,其操作步驟是先導入模塊,再調用模塊中包含的函數,可將自定義模塊放入當前目錄,便於解釋器路徑搜索,以下是導入自定義hello.py模塊,並調用World函數的實例:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
#導入模塊
import hello
#現在可以調用模塊里包含的函數了
support.print_func("World")
輸出結果為:
Hello World!
以上實例也可以採用from…import的方法進行實現,是指從一個模塊中導入指定的部分到當前命名空間中,以上功能可寫成:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
from hello import World
如果要將模塊中的所有內容全部導入當前命名空間,可採用from…import*的方法,具體實例如下:
#!/usr/bin/python
#-*- coding: UTF-8 -*-
from hello import *
還需注意,當要導入一個模塊時,Python解釋器會對模塊的位置進行搜索,具體搜索順序規律如下:
1.當前目錄;
2.如果不在當前目錄,Python則搜索在shell變數PYTHONPATH下的每個目錄;
3.如果都找不到,Python會察看默認路徑。
4. python如何定義新對象
Python可以自定義新的類,然後用這些類創建新對象。
classFruit:
def__init__(self,name):
self.name=name
defprntName(self):
printself.name
這是一個簡單的Python類的實現。
fruit=Fruit('apple')
fruit.prntName()
這樣子,我們就創建了一個自定義的新的對象了。
5. Python對象
眾所周知,Python是一門面向對象的語言,在Python無論是數值、字元串、函數亦或是類型、類,都是對象。
對象是在 堆 上分配的結構,我們定義的所有變數、函數等,都存儲於堆內存,而變數名、函數名則是一個存儲於 棧 中、指向堆中具體結構的引用。
要想深入學習Python,首先需要知道Python對象的定義。
我們通常說的Python都是指CPython,底層由C語言實現,源碼地址: cpython [GitHub]
Python對象的定義位於 Include/object.h ,是一個名為 PyObject 的結構體:
Python中的所有對象都繼承自PyObejct,PyObject包含一個用於垃圾回收的雙向鏈表,一個引用計數變數 ob_refcnt 和 一個類型對象指針 ob_type
從PyObejct的注釋中,我們可以看到這樣一句:每個指向 可變大小Python對象 的指針也可以轉換為 PyVarObject* (可變大小的Python對象會在下文中解釋)。 PyVarObejct 就是在PyObject的基礎上多了一個 ob_size 欄位,用於存儲元素個數:
在PyObject結構中,還有一個類型對象指針 ob_type ,用於表示Python對象是什麼類型,定義Python對象類型的是一個 PyTypeObject 介面體
實際定義是位於 Include/cpython/object.h 的 _typeobject :
在這個類型對象中,不僅包含了對象的類型,還包含了如分配內存大小、對象標准操作等信息,主要分為:
以Python中的 int類型 為例,int類型對象的定義如下:
從PyObject的定義中我們知道,每個對象的 ob_type 都要指向一個具體的類型對象,比如一個數值型對象 100 ,它的ob_type會指向 int類型對象PyLong_Type 。
PyTypeObject結構體第一行是一個PyObject_VAR_HEAD宏,查看宏定義可知PyTypeObject是一個變長對象
也就是說,歸根結底 類型對象也是一個對象 ,也有ob_type屬性,那 PyLong_Type 的 ob_type 是什麼呢?
回到PyLong_Type的定義,第一行 PyVarObject_HEAD_INIT(&PyType_Type, 0) ,查看對應的宏定義
由以上關系可以知道, PyVarObject_HEAD_INIT(&PyType_Type, 0) = { { _PyObject_EXTRA_INIT 1, &PyType_Type } 0} ,將其代入 PyObject_VAR_HEAD ,得到一個變長對象:
這樣看就很明確了,PyLong_Type的類型就是PyType_Typ,同理可知, Python類型對象的類型就是PyType_Type ,而 PyType_Type對象的類型是它本身
從上述內容中,我們知道了對象和對象類型的定義,那麼根據定義,對象可以有以下兩種分類
Python對象定義有 PyObject 和 PyVarObject ,因此,根據對象大小是否可變的區別,Python對象可以劃分為 可變對象(變長對象) 和 不可變對象(定長對象)
原本的對象a大小並沒有改變,只是s引用的對象改變了。這里的對象a、對象b就是定長對象
可以看到,變數l仍然指向對象a,只是對象a的內容發生了改變,數據量變大了。這里的對象a就是變長對象
由於存在以上特性,所以使用這兩種對象還會帶來一種區別:
聲明 s2 = s ,修改s的值: s = 'new string' ,s2的值不會一起改變,因為只是s指向了一個新的對象,s2指向的舊對象的值並沒有發生改變
聲明 l2 = l ,修改l的值: l.append(6) ,此時l2的值會一起改變,因為l和l2指向的是同一個對象,而該對象的內容被l修改了
此外,對於 字元串 對象,Python還有一套內存復用機制,如果兩個字元串變數值相同,那它們將共用同一個對象:
對於 數值型 對象,Python會默認創建0~2 8 以內的整數對象,也就是 0 ~ 256 之間的數值對象是共用的:
按照Python數據類型,對象可分為以下幾類:
Python創建對象有兩種方式,泛型API和和類型相關的API
這類API通常以 PyObject_xxx 的形式命名,可以應用在任意Python對象上,如:
使用 PyObjecg_New 創建一個數值型對象:
這類API通常只能作用於一種類型的對象上,如:
使用 PyLong_FromLong 創建一個數值型對象:
在我們使用Python聲明變數的時候,並不需要為變數指派類型,在給變數賦值的時候,可以賦值任意類型數據,如:
從Python對象的定義我們已經可以知曉造成這個特點的原因了,Python創建對象時,會分配內存進行初始化,然後Python內部通過 PyObject* 變數來維護這個對象,所以在Python內部各函數直接傳遞的都是一種泛型指針 PyObject* ,這個指針所指向的對象類型是不固定的,只能通過所指對象的 ob_type 屬性動態進行判斷,而Python正是通過 ob_type 實現了多態機制
Python在管理維護對象時,通過引用計數來判斷內存中的對象是否需要被銷毀,Python中所有事物都是對象,所有對象都有引用計數 ob_refcnt 。
當一個對象的引用計數減少到0之後,Python將會釋放該對象所佔用的內存和系統資源。
但這並不意味著最終一定會釋放內存空間,因為頻繁申請釋放內存會大大降低Python的執行效率,因此Python中採用了內存對象池的技術,是的對象釋放的空間會還給內存池,而不是直接釋放,後續需要申請空間時,優先從內存對象池中獲取。
6. python中的函數參數為自定義類對象,如何強制轉換
python不需要也沒有強制轉換
對象之間的耦合通過對象的方法實現
只要你有這個方法就可以調用,因為python函數的參數是沒有類型的
7. Python的類和對象入門
本文來說說Python中的類與對象,Python這門語言是無處不對象,如果你曾淺要了解過Python,你應該聽過Python是一種面向對象編程的語言,所以你經常可能會看到面向「對象」編程這類段子,而面向對象編程的語言都會有三大特徵:封裝、繼承、多態。
我們平時接觸到的很多函數、方法的操作都具有這些性質,我們只是會用,但還沒有去深入了解它的本質,下面就介紹一下關於類和對象的相關知識。
封裝這個概念應該並不陌生,比如我們把一些數據封裝成一個列表,這就屬於數據封裝,我們也可以將一些代碼語句封裝成一個函數方便調用,這就是代碼的封裝,我們也可以將數據和代碼封裝在一起。用術語表示的話,就是可以將屬性和方法進行封裝,從而得到對象。
首先我們可以定義一個類,這個類中有屬性和方法,但有的夥伴會比較好奇,屬性和方法不是會封裝成對象嘛,為什麼又變成類了?舉個例子,類就好比是一個毛坯房,而對象是在毛坯房的基礎上改造成的精裝房。
在類定義完成時就創建了一個類對象,它是對類定義創建的命名空間進行了一個包裝。類對象支持兩種操作:屬性引用和實例化。
屬性引用的語法就是一般的標准語法:obj.name。比如XiaoMing.height和XiaoMing.run就是屬性引用,前者會返回一條數據,而後者會返回一個方法對象。
這里也支持對類屬性進行賦值操作,比如為類中的weight屬性賦予一個新值。
而類的實例化可以將類對象看作成一個無參函數的賦值給一個局部變數,如下:
ming就是由類對象實例化後創建的一個實例對象,通過實例對象也可以調用類中的屬性和方法。
類在實例化過程中並不都是像上面例子一樣簡單的,一般類都會傾向將實例對象創建為有初始狀態的,所以在類中可能會定義一個__init__的魔法方法,這個方法就可以幫助接收、傳入參數。
而一個類如果定義了__init__方法,那麼在類對象實例化的過程中就會自動為新創建的實例化對象調用__init__方法,請看下面這個例子。
可以看到在__init__()中傳入了參數x和y,然後在print_coor中需要接收參數x和y,接下來通過實例化這個類對象,驗證一下參數是否能通過__init__()傳遞到類的實例化操作中。
所謂繼承就是一個新類在另一個類的基礎上構建而成,這個新類被稱作子類或者派生類,而另一個類被稱作父類、基類或者超類,而子類會繼承父類中已有的一些屬性和方法。
比如上面這個例子,我並沒有將list_定義成一個列表,但它卻能調用append方法。原因是類Mylist繼承於list這個基類,而list_又是Mylist的一個實例化對象,所以list_也會擁有父類list擁有的方法。當然可以通過自定義類的形式實現兩個類之間的繼承關系,我們定義Parent和Child兩個類,Child中沒有任何屬性和方法,只是繼承於父類Parent。
當子類中定義了與父類中同名的方法或者屬性,則會自動覆蓋父類對應的方法或屬性,還是用上面這個例子實現一下,方便理解。
可以看到子類Child中多了一個和父類Parent同名的方法,再實例化子類並調用這個方法時,最後調用的是子類中的方法。Python中繼承也允許多重繼承,也就是說一個子類可以繼承多個父類中的屬性和方法,但是這類操作會導致代碼混亂,所以大多數情況下不推薦使用,這里就不過多介紹了。
多態比較簡單,比如定義兩個類,這兩個類沒有任何關系,只是兩個類中有同名的方法,而當兩個類的實例對象分別調用這個方法時,不同類的實例對象調用的方法也是不同的。
上面這兩個類中都有introce方法,我們可以實例化一下兩個類,利用實例對象調用這個方法實現一下多態。
判斷一個類是否是另一個類的子類,如果是則返回True,反之則返回False。
需要注意的有兩點:
判斷一個對象是否為一個類的實例對象,如果是則返回True,反之則返回False。
需要注意的有兩點:
判斷一個實例對象中是否包含一個屬性,如果是則返回True,反之則返回False。
需要注意的是第二個參數name必須為字元串形式傳入,如果不是則會返回False。
8. python如何把一個序列化的自定義類對象存到文件
Python有專門的序列化模塊pickle用來序列化/反序列化對象,可以查一下它的使用。
pickle是純Python寫的,它還有個替代模塊cPickle,是C語言寫的,速度快很多。
9. python3自定義迭代器對象如何用next方法依次迭代
Python 3.x與Python 2.x之間存在著較多的語法細節差異。今天在看Python核心編程的時候,說到了自定義迭代器對象。於是動手將源碼打了一遍,原書代碼如下:
class AnyIter(object):
def __init__(self, data, safe=False):
""" The initialization of iterators """
self.safe = safe
self.iter = iter(data)
def __iter__(self):
""" return a iterator """
return self
def next(self, count=1):
""" Return arbitrary numbers of elements """
retval = []
for item in range(count):
try:
retval.append(self.iter.next())
except StopIteration:
if self.safe:
break
else:
raise # reraise the exception again
return retval
if __name__ == '__main__':
a = AnyIter(range(10), True)
b = iter(a)
for item in range(1,5):
print('{}:{}'.format(item, a.next(item)))
我機器上裝的是Python 3.3.2,在控制台運行該腳本的時候直接拋出異常TypeError:
說是iter()返回的是一個非迭代器類型的對象。前後對照了一下,並沒有發現哪裡有錯誤啊。於是嘗試使用Ipython(Python 版本是2.7.5)來運行該代碼,得出完美結果。於是考慮是不是版本的問題。求助google,在stackoverflow上找到一個帖子,找到了關鍵原因:
於是將上述代碼中調用next()的地方全部替換為__next__(),最後在控制台運行該代碼,正確得到了預期的結果:
查閱Python 3.3.2 附帶的用戶手冊,果然得到如下結果:
問題得到解決:Python核心編程使用的是Python 2.x,版本差異使得該狀況得以發生。還是得動手,不然這樣的差異無法得知。
10. Python 使用對象模型來存儲數據
Python使用對象模型來存儲數據。構造任何類型的值都是一個對象。盡管Python通常被當成一種「面向對象的編程語言」,但你完全能夠寫出不使用任何類和實例的實用腳本。不過Python的對象語法和架構鼓勵我們使用這些特性,下面讓我們仔細研究一下Python對象。所有的Python對像都擁有三個特性:身份,類型和值。
身份:每一個對象都有一個唯一的身份標識自己,任何對象的身份可以使用內建函數id()來得到。這個值可以被認為是該對象的內存地址。你極少會用到這個值,也不用太關心它究竟是什麼。
類型對象的類型決定了該對象可以保存什麼類型的值,可以進行什麼樣的操作,以及遵循什麼樣的規則。你可以用內建函數type0查看Python對象的類型。因為在Python中類型也是對象(還記得我們提到Python是面向對象的這句話嗎?),所以type0返回的是對象而不是簡單的字元串。
值:對象表示的數據項。
上面三個特性在對象創建的時候就被賦值,除了值之外,其他兩個特性都是只讀的。對於新式類型和類,對象的類型也是可以改變的,不過並不推薦初學者這樣做。如果對象支持更新操作,那麼它的值就可以改變,否則它的值也是只讀的。對象的值是否可以更改被稱為對象的可改變性(mutability),我們會在後面的4.7小節中討論這個問題。只要一個對象還沒有被銷毀,這些特性就一直存在。Python有一系列的基本(內建)數據類型,必要時也可以創建自定義類型來滿足你對應用程序的需求。絕大多數應用程序通常使用標准類型,對特定的數據存儲則通過創建和實例化類來實現。