導航:首頁 > 編程語言 > python對象屬性和行為最多數量

python對象屬性和行為最多數量

發布時間:2023-02-05 12:17:30

A. 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中採用了內存對象池的技術,是的對象釋放的空間會還給內存池,而不是直接釋放,後續需要申請空間時,優先從內存對象池中獲取。

B. python類的屬性有哪幾種如何訪問它們

屬性的訪問機制

一般情況下,屬性訪問的默認行為是從對象的字典中獲取,並當獲取不到時會沿著一定的查找鏈進行查找。例如a.x的查找鏈就是,從a.__dict__['x'],然後是type(a).__dict__['x'],再通過type(a)的基類開始查找。

若查找鏈都獲取不到屬性,則拋出AttributeError異常。

一、__getattr__方法

這個方法是當對象的屬性不存在是調用。如果通過正常的機制能找到對象屬性的話,不會調用__getattr__方法。

classA:
a=1
def__getattr__(self,item):
print('__getattr__call')
returnitem

t=A()
print(t.a)
print(t.b)
#output
1
__getattr__call
b

二、__getattribute__方法

這個方法會被無條件調用。不管屬性存不存在。如果類中還定義了__getattr__,則不會調用__getattr__()方法,除非在__getattribute__方法中顯示調用__getattr__()或者拋出了AttributeError。

classA:
a=1
def__getattribute__(self,item):
print('__getattribute__call')
raiseAttributeError

def__getattr__(self,item):
print('__getattr__call')
returnitem

t=A()
print(t.a)
print(t.b)

所以一般情況下,為了保留__getattr__的作用,__getattribute__()方法中一般返回父類的同名方法:

def__getattribute__(self,item):
returnobject.__getattribute__(self,item)

使用基類的方法來獲取屬性能避免在方法中出現無限遞歸的情況。

三、__get__方法

這個方法比較簡單說明,它與前面的關系不大。

如果一個類中定義了__get__(),__set__()或__delete__()中的任何方法。則這個類的對象稱為描述符。

classDescri(object):
def__get__(self,obj,type=None):
print("callget")

def__set__(self,obj,value):
print("callset")

classA(object):
x=Descri()

a=A()
a.__dict__['x']=1#不會調用__get__
a.x#調用__get__
如果查找的屬性是在描述符對象中,則這個描述符會覆蓋上文說的屬性訪問機制,體現在查找鏈的不同,而這個行文也會因為調用的不同而稍有不一樣:

C. 關於Python類和對象的問題

def__area(self):
returnself.a*self.b
def__perimeter(self):
return2*(self.a+self.b)
def__outputarea(self):
print(self.__area())
def__outputperimeter(self):
print(self.__perimeter())

D. python 里的屬性是什麼意思

樓上的 ,"在python中一切皆對象" 明顯不對,誰說在python中一切皆對象

屬性,屬性方法,方法? 原來的英文貼出來才知道你說的是什麼

E. python對象是什麼概念

所說所有的變數都是對象。 對象在python里,其實是一個指針,指向一個數據結構,數據結構里有屬性,有方法。x0dx0a x0dx0a對象通常就是指變數。從面向對象OO的概念來講,對象是類的一個實例。在python里很簡單,對象就是變數。x0dx0a x0dx0aclass A:x0dx0a myname="class a"x0dx0a上面就是一個類。不是對象x0dx0aa=A()x0dx0a這里變數a就是一個對象。x0dx0a它有一個屬性(類屬性),myname,你可以顯示出來x0dx0aprint a.mynamex0dx0a x0dx0a所以,你看到一個變數後面跟點一個小數點。那麼小數點後面就是它的屬性或者是方法。帶括弧的方法。不帶就是屬性。

F. python 求最大值

####求10個數據的最大值########
list=[]
for i in range(10):#這里可以設置數據的多少
list.append(float(input("請輸入數據"))) #輸入數據,如果都是整數可以把float改為int
max=list[0]
for i in range(10):#這里數據與上面的for裡面的保持一致
if list[i]>max:#如果數據比max大就會更新max
max=list[i]
print("最大值為:%f"%max)#輸出
#望採納

G. 如何理解python的類與對象

1.萬物皆對象,把對象歸類就有了類;
類也是對象,把類歸了類就是超類;
以此類推.
2.對象往往具備(也可以不具備) 行為和屬性.
行為我們通常用 函數(function) 實現
屬性(attribute)我們通常用 變數 實現
3.因為萬物皆對象,所以"函數"&"變數"也是對象
所以 "變數"可以有自己的"函數", "函數"也可以有自己的變數.
4.藉此機會練習五筆,所以故意多打了一些字.

H. python中類對象的理解總結

9.3.2. 類對象
類對象支持兩種操作:屬性引用和實例化。
屬性引用 使用和 Python 中所有的屬性引用一樣的標准語法:obj.name。類對象創建後,類命名空間中所有的命名都是有效屬性名。所以如果類定義是這樣:
class MyClass:
"""A simple example class"""
i = 12345
def f(self):
return 'hello world'
那麼 MyClass.i 和 MyClass.f 是有效的屬性引用,分別返回一個整數和一個方法對象。也可以對類屬性賦值,你可以通過給 MyClass.i 賦值來修改它。 __doc__ 也是一個有效的屬性,返回類的文檔字元串:"A simple example class"。
類的 實例化 使用函數符號。只要將類對象看作是一個返回新的類實例的無參數函數即可。例如(假設沿用前面的類):
x = MyClass()
以上創建了一個新的類 實例 並將該對象賦給局部變數 x。
這個實例化操作(「調用」一個類對象)來創建一個空的對象。很多類都傾向於將對象創建為有初始狀態的。因此類可能會定義一個名為 __init__() 的特殊方法,像下面這樣:
def __init__(self):
self.data = []
類定義了 __init__() 方法的話,類的實例化操作會自動為新創建的類實例調用 __init__() 方法。所以在下例中,可以這樣創建一個新的實例:
x = MyClass()
當然,出於彈性的需要,__init__() 方法可以有參數。事實上,參數通過 __init__() 傳遞到類的實例化操作上。例如,
>>> 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)

I. 如何理解關於python 面向對象的特性

python中一切皆為對象
其實面向對象沒什麼高大上的東西,只不過把我們平時對於事物的描述和動作系統的總結成了一個定義事物的方法而已。
我們平時向別人介紹一個他(她)從未見過的東西,會從外形和外貌特徵來說明這個東西,比如顏色,大小等,這就對象的屬性。還會介紹這個東西能做什麼或者有什麼用,這就是對象的方法。所以用屬性和方法就可以定義一個對象。也就是說一個對象包含了各種屬性和方法。
在python中使用對象屬性和方法的記法為:object.attribute 或 object.method()
Python中創建對象的第一步是建立一個類(class),這個類就類似於我們區分動物和植物。動物類和植物類各有自己的特徵,當我們見到一個事物時,如果它滿足動物的特徵,我們就說它是動物;如果它滿足植物的特徵,那麼它就屬於植物。同樣的當我們在python中建立一個類時,就要說名這個類的屬性有什麼,方法有什麼。然後再創建屬於這個類的具體實例,也就是對象。那麼這個對象也就有了這個類的屬性和方法。但具體的屬性和方法根據具體對象而定。就像動物類的屬性就是有耳朵,有眼睛,有皮毛,方法就是移動,進食等等,具體對象比如說是兔子那就是有長長的耳朵,紅色的眼睛,白色的皮毛。方法就是奔跑,進食就是吃胡蘿卜。這樣理解類和對象或者實例就沒什麼抽象的了。
__init__(): 創建類的默認屬性,也稱初始化
__str__() : 返回對象的字元串表達式
多態:對於不同的類可以有同名的方法,同名的方法應用到不同的類可以有不同的行為。
形如:
class Triangle:
def __init__(self, width,height):
self.width = width
self.height = height
def getArea(self):
area = self.width * self.height / 2.0
return area
class Square:
def __init__(self,size):
self.size = size
def getArea(self):
area = self.size * self.size
return area
繼承:類可以從其他類繼承屬性和方法;從其他類繼承屬性或方法稱為派生類或者子類。
形如:class Animal:
def __init__(self,name):
self.name = name
class Dog(Animal):
def __init__(self,color):
self.color = color
def runSpeed():
pass
這樣Dog就繼承了Animal的name屬性。
對象的方法代碼暫未想出可以用pass佔位。

J. python內存管理機制

由於python中萬物皆對象,所以python的存儲問題是對象的存儲問題。實際上,對於每個對象,python會分配一塊內存空間去存儲它。
那麼python是如何進行內存分配,如何進行內存管理,又是如何釋放內存的呢?
總結起來有一下幾個方面:引用計數,垃圾回收,內存池機制

python內部使用引用計數,來保持追蹤內存中的對象,Python內部記錄了對象有多少個引用,即引用計數

1、對象被創建 a= 'abc'
2、對象被引用 b =a
3、對象被其他的對象引用 li = [1,2,a]
4、對象被作為參數傳遞給函數:foo(x)

1、變數被刪除 del a 或者 del b
2、變數引用了其他對象 b = c 或者 a = c
3、變數離開了所在的作用域(函數調用結束) 比如上面的foo(x)函數結束時,x指向的對象引用減1。
4、在其他的引用對象中被刪除(移除) li.remove(a)
5、窗口對象本身被銷毀:del li,或者窗口對象本身離開了作用域。

即對象p中的屬性引用d,而對象d中屬性同時來引用p,從而造成僅僅刪除p和d對象,也無法釋放其內存空間,因為他們依然在被引用。深入解釋就是,循環引用後,p和d被引用個數為2,刪除p和d對象後,兩者被引用個數變為1,並不是0,而python只有在檢查到一個對象的被引用個數為0時,才會自動釋放其內存,所以這里無法釋放p和d的內存空間

垃圾回收機制: ① 引用計數 , ②標記清除 , ③分帶回收

引用計數也是一種垃圾收集機制, 而且也是一種最直觀, 最簡單的垃圾收集技術.當python某個對象的引用計數降為 0 時, 說明沒有任何引用指向該對象, 該對象就成為要被回收的垃圾了.(如果出現循環引用的話, 引用計數機制就不再起作用了)

優點:簡單實時性,缺點:維護引用計數消耗資源,且無法解決循環引用。

如果兩個對象的引用計數都為 1 , 但是僅僅存在他們之間的循環引用,那麼這兩個對象都是需要被回收的, 也就是說 它們的引用計數雖然表現為非 0 , 但實際上有效的引用計數為 0 ,.所以先將循環引用摘掉, 就會得出這兩個對象的有效計數.

標記清除演算法也有明顯的缺點:清除非活動的對象前它必須順序掃描整個堆內存,哪怕只剩下小部分活動對象也要掃描所有對象。

為了提高效率,有很多對象,清理了很多次他依然存在,可以認為,這樣的對象不需要經常回收,可以把它分到不同的集合,每個集合回收的時間間隔不同。簡單的說這就是python的分代回收。

具體來說,python中的垃圾分為1,2,3代,在1代里的對象每次回收都會去清理,當清理後有引用的對象依然存在,此時他會進入2代集合,同理2代集合清理的時候存在的對象會進入3代集合。

每個集合的清理時間如何分配:會先清理1代垃圾,當清理10次一代垃圾後會清理一次2代垃圾,當清理10次2代垃圾後會清理3代垃圾。

在Python中,許多時候申請的內存都是小塊的內存,這些小塊內存在申請後,很快又會被釋放,當創建大量消耗小內存的對象時,頻繁調用new/malloc會導致大量的內存碎片,致使效率降低。
內存池的概念就是預先在內存中申請一定數量的,大小相等的內存塊留作備用,當有新的內存需求時,就先從內存池中分配內存給這個需求,不夠了之後再申請新的內存。這樣做最顯著的優勢就是能夠減少內存碎片,提升效率。

Python中有分為大內存和小內存:(256K為界限分大小內存)
大小小於256kb時,pymalloc會在內存池中申請內存空間,當大於256kb,則會直接執行 new/malloc 的行為來申請新的內存空間

在python中 -5到256之間的數據,系統會默認給每個數字分配一個內存區域,其後有賦值時都會指向固定的已分配的內存區域

在運行py程序的時候,解釋器會專門分配一塊空白的內存,用來存放純單詞字元組成的字元串(數字,字母,下劃線)

字元串賦值時,會先去查找要賦值的字元串是否已存在於內存區域,已存在,則指向已存在的內存,不存在,則會在大整數池中分配一塊內存存放此字元串

閱讀全文

與python對象屬性和行為最多數量相關的資料

熱點內容
羅曼史生孩子在那一段在幾分鍾 瀏覽:953
成龍40部經典電影 瀏覽:795
程序員連出兩次線上事故 瀏覽:427
啄木鳥電影什麼意思 瀏覽:292
主角叫柱子的鄉村小說 瀏覽:962
肉特別多的電影 瀏覽:970
好的在觀看網站 瀏覽:307
vip免費影視劇網站 瀏覽:924
恐怖鬼片免費版在線觀看 瀏覽:539
印度神話電影排行前十 瀏覽:510
主角開飛機重生流 瀏覽:760
java函數式編程教程 瀏覽:271
天正圖紙加密後的效果 瀏覽:909
泰安汽車解壓郵政網點 瀏覽:410
泰國鬼片在線觀看免費收看 瀏覽:695
彼時曾相伴免費觀看完整版 瀏覽:254
網站在線觀看什 瀏覽:159
食嬰鬼整部電影 瀏覽:360
印度電影愛經 瀏覽:642
搜播比神馬更好看的影視 瀏覽:82