python 物件的屬性

2022-05-02 11:48:12 字數 3977 閱讀 7351

**:

python一切皆物件(object),每個物件都可能有多個屬性(attribute)。python的屬性有一套統一的管理方案。

物件的屬性可能來自於其類定義,叫做類屬性(class attribute)。類屬性可能來自類定義自身,也可能根據類定義繼承來的。乙個物件的屬性還可能是該物件例項定義的,叫做物件屬性(object attribute)。

物件的屬性儲存在物件的__dict__屬性中。__dict__為乙個詞典,鍵為屬性名,對應的值為屬性本身。我們看下面的類和物件。chicken類繼承自bird類,而summer為chicken類的乙個物件。

class bird(object):

feather = true

class chicken(bird):

fly = false

def __init__(self, age):

self.age = age

summer = chicken(2)

print(bird.__dict__)

print(chicken.__dict__)

print(summer.__dict__)

下面為我們的輸出結果:

第一行為bird類的屬性,比如feather。第二行為chicken類的屬性,比如fly和__init__方法。第三行為summer物件的屬性,也就是age。有一些屬性,比如__doc__,並不是由我們定義的,而是由python自動生成。此外,bird類也有父類,是object類(正如我們的bird定義,class bird(object))。這個object類是python中所有類的父類。

可以看到,python中的屬性是分層定義的,比如這裡分為object/bird/chicken/summer這四層。當我們需要呼叫某個屬性的時候,python會一層層向上遍歷,直到找到那個屬性。(某個屬性可能出現再不同的層被重複定義,python向上的過程中,會選取先遇到的那乙個,也就是比較低層的屬性定義)。

當我們有乙個summer物件的時候,分別查詢summer物件、chicken類、bird類以及object類的屬性,就可以知道summer物件所有的__dict__,就可以找到通過物件summer可以呼叫和修改的所有屬性了。下面兩種屬性修改方法等效:

summer.__dict__['age'] = 3

print(summer.__dict__['age'])

summer.age = 5

print(summer.age)

(上面的情況中,我們已經知道了summer物件的類為chicken,而chicken類的父類為bird。如果只有乙個物件,而不知道它的類以及其他資訊的時候,我們可以利用__class__屬性找到物件的類,然後呼叫類的__base__屬性來查詢父類)

print summer.__class__.__base__.feather
輸出:true

同乙個物件的不同屬性之間可能存在依賴關係。當某個屬性被修改時,我們希望依賴於該屬性的其他屬性也同時變化。這時,我們不能通過__dict__的方式來靜態的儲存屬性。python提供了多種即時生成屬性的方法。其中一種稱為特性(property)。特性是特殊的屬性。比如我們為chicken類增加乙個特性adult。當物件的age超過1時,adult為true;否則為false:

class bird(object):

feather = true

class chicken(bird):

fly = false

def __init__(self, age):

self.age = age

def getadult(self):

if self.age > 1.0: return true

else: return false

adult = property(getadult) # property is built-in

summer = chicken(2)

print(summer.adult)

summer.age = 0.5

print(summer.adult)

特性使用內建函式property()來建立。property()最多可以載入四個引數。前三個引數為函式,分別用於處理查詢特性、修改特性、刪除特性。最後乙個引數為特性的文件,可以為乙個字串,起說明作用。

我們使用下面乙個例子進一步說明:

class num(object):

def __init__(self, value):

self.value = value

def getneg(self):

return -self.value

def setneg(self, value):

self.value = -value

def delneg(self):

print("value also deleted")

del self.value

neg = property(getneg, setneg, delneg, "i'm negative")

x = num(1.1)

print(x.neg)

x.neg = -22

print(x.value)

print(num.neg.__doc__)

del x.neg

上面的num為乙個數字,而neg為乙個特性,用來表示數字的負數。當乙個數字確定的時候,它的負數總是確定的;而當我們修改乙個數的負數時,它本身的值也應該變化。這兩點由getneg和setneg來實現。而delneg表示的是,如果刪除特性neg,那麼應該執行的操作是刪除屬性value。property()的最後乙個引數("i'm negative")為特性negative的說明文件。

我們可以用__getattr__(self, name)來查詢即時生成的屬性。當我們查詢乙個屬性時,如果通過__dict__方法無法找到該屬性,那麼python會呼叫物件的__getattr__方法,來即時生成該屬性。比如:

class bird(object):

feather = true

class chicken(bird):

fly = false

def __init__(self, age):

self.age = age

def __getattr__(self, name):

if name == 'adult':

if self.age > 1.0: return true

else: return false

else: raise attributeerror(name)

summer = chicken(2)

print(summer.adult)

summer.age = 0.5

print(summer.adult)

print(summer.male)

每個特性需要有自己的處理函式,而__getattr__可以將所有的即時生成屬性放在同乙個函式中處理。__getattr__可以根據函式名區別處理不同的屬性。比如上面我們查詢屬性名male的時候,raise attributeerror。

(python中還有乙個__getattribute__特殊方法,用於查詢任意屬性。__getattr__只能用來查詢不在__dict__系統中的屬性)

__setattr__(self, name, value)和__delattr__(self, name)可用於修改和刪除屬性。它們的應用面更廣,可用於任意屬性。

即時生成屬性還可以使用其他的方式,比如descriptor(descriptor類實際上是property()函式的底層,property()實際上建立了乙個該類的物件)。有興趣可以進一步查閱。

__dict__分層儲存屬性。每一層的__dict__只儲存該層新增的屬性。子類不需要重複儲存父類中的屬性。

即時生成屬性是值得了解的概念。在python開發中,你有可能使用這種方法來更合理的管理物件的屬性。

python沒有屬性的物件 物件沒有屬性g

我正在使用python 3.3中的tkinter模組,對此我還比較陌生,正在使用輸入框。出於某種原因,當我執行以下 時,我收到一條錯誤訊息,說attribute error nonetype 物件沒有屬性 get 有人能解釋一下原因嗎?我做了乙個類似的程式,乙個條目工作得很好。from tkinte...

python 物件,屬性的方法

物件的建立和銷毀 new cls args,kwargs 建立新例項時呼叫的類方法 這個在 init 的前面呼叫 init self args,kwargs 初始化新實列時呼叫 del self 銷毀物件時呼叫 如下方法用於建立物件的各種字串表示 format self,format spec 建立...

Python物件屬性的操作

如何給物件新增 修改屬性 給物件新增屬性 p1.name zhangsan print p1.name 修改物件屬性值 p1.name lisi print p1.name setattr 是乙個內建函式,是給物件新增屬性和值 setattr 物件,屬性名 字串 屬性值 setattr p1,key...