遇到這樣一個情況,要列印出一個對象的各種屬性。但是不同對象的屬性名都不一樣,結構也不同,無法寫一個代碼來實作。然後我找到了<code>__dict__</code>,使用這個屬性,可以動态擷取到對象的所有屬性,不包括公用屬性。
通過<code>__dict__</code>,就可以動态的擷取到對象的全部屬性。獲得的是一個字典,屬性名是字典的key,屬性值是字典的value。從輸出看,私有屬性也可以獲得,隻是不包括公有屬性。
然後,如果隻想要屬性值的話,可以對字典再加工。複習一下字典的3個方法:
<code>dict.items()</code> :用元祖來存放key和vlaue
<code>dict.keys()</code> : 隻包含key
<code>dict.values()</code> : 隻包含value
上面3個方法傳回的都是一個可疊代對象,可以用for周遊,但不是疊代器,不能用next方法。
然後用下面的方法列印
最後拆分一下列印的時候用到的方法
<code>a = dict1.items()</code> 這個是可疊代對象,可以用for周遊
<code>b = ("%s:%s"%item for item in a)</code> 用for循環周遊a,每一項是個元祖,把元祖轉成"%s:%s"的字元串形式。最外面的( )就是轉成一個疊代器。也可以用[ ],轉成清單。
<code>c = ‘\n’.join(b)</code> 最後用join()方法完成字元串的拼接
又發現一個更好用的方法,并且可以擷取到公有屬性了。<code>__str__</code>方法是在列印這個對象的時候,不再列印對象的記憶體位址,而是列印<code>__str__</code>方法的傳回值:
這裡要注意,傳回值必須是字元串,是以得傳一個資料類型
<code>return " ".join(str(item) for item in (self.display,self.name,self.age,self.course,self.__salary))</code> 這個也可以這麼寫
<code>return "%s %s %s %s %s"%(self.display,self.name,self.age,self.course,self.__salary)</code> 這麼寫雖然好了解,但是前面的%s的數量必須和後面的變量一緻,如果要加1個或減1個變量,前後都得改。
<code>__str__</code>方法可以完全自定義自己對象的輸出格式,既然是自定義的方法,那麼還可以加上參數控制。但是調用的時候似乎并沒有地方填參數。
其實是在print調用對象的時候,系統已經幫我們自動将print指向了<code>__str__</code>方法,也就是說 <code>print(t1)</code> 其實執行的是 <code>print(t1.__str__())</code> ,這個時候我們就可以自己寫全,然後加上參數。
其實這裡并沒不是列印了所有的屬性,而是我們自定義了列印内容。但是自定義的位置是在類中的,這個位置是可以擷取到全部屬性的。
其實就是把上面2個方法一起用。其實有上面2個方法應該就可以了,不過既然都搞明白了,留個記錄也好。
先提一個點,在定義了<code>__str__</code>方法後,雖然列印出來是字元串,但是在其他時候傳的值還是對象。如果想擷取就是列印的值而不是對象,那麼還是用<code>對象__str__()</code> 來傳遞,下面就是最終的例子:
<code>print(t1_str,type(t1_str)) # 這裡擷取到的就是字元串類型了</code>
<code></code>
<code>本文轉自騎士救兵51CTO部落格,原文連結:</code>http://blog.51cto.com/steed/2046408,如需轉載請自行聯系原作者