1. 程式人生 > >一個在交流群裡討論過兩輪的問題,答案竟然跟一個 PEP 有關

一個在交流群裡討論過兩輪的問題,答案竟然跟一個 PEP 有關

Python 中有沒有辦法通過類方法找到其所屬的類? 這個問題看起來不容易理解,我可以給出一個例子: ```python class Test: @xxx def foo(self): pass ``` 現在有一個類和一個類方法,其中類方法上有一個裝飾器。 **我們的問題就是要在裝飾器程式碼中動態地獲得 Test 這個類(類名+類物件)。** 去年 11 月份的時候,我在微信讀者群裡提出了這個問題,當時引起了小範圍的討論。 沒想到在今年上個月的時候,群裡又有人提了同樣的問題(我在討論結束後才看到),而且最終都找到了 stackoverflow 上一個同樣的問題: ![](http://ww1.sinaimg.cn/large/68b02e3bgy1ghocppegtfj20bh0m8abo.jpg) stackoverflow 上的問題提得很明確:[Get defining class of unbound method object in Python 3](https://stackoverflow.com/questions/3589311/get-defining-class-of-unbound-method-object-in-python-3) 。但是 unbound method 的叫法已經不常見了,詳細的討論也就不展開了,感興趣的同學可以去查閱。 這個問題的關鍵是要使用在 Python 3.3 中引入的\_\_qualname\_\_ 屬性,通過它可以獲取上層類的名稱。 鋪墊了這麼多,開始進入本文的正題了:**\_\_qualname\_\_ 屬性是什麼東西?為什麼 Python 3 要特別引入它呢?** 下文是 PEP-3155 的翻譯摘錄,清楚地說明了這個屬性的來龍去脈。 完整內容可在 Github 倉庫檢視:[https://github.com/chinesehuazhou/peps-cn/blob/master/StandardsTrack/3155--%E7%B1%BB%E5%92%8C%E6%96%B9%E6%B3%95%E7%9A%84%E7%89%B9%E5%AE%9A%E5%90%8D%E7%A7%B0.md](https://github.com/chinesehuazhou/peps-cn/blob/master/StandardsTrack/3155--%E7%B1%BB%E5%92%8C%E6%96%B9%E6%B3%95%E7%9A%84%E7%89%B9%E5%AE%9A%E5%90%8D%E7%A7%B0.md) -------------------摘錄開始-------------------- ## 原理 一直以來,對於巢狀類的自省,Python 的支援很不夠。給定一個類物件,根本不可能知道它是在某個類中定義的,還是在頂層模組中定義的;而且,如果是前者,也不可能知道它具體是在哪個類中定義的。雖然巢狀類通常被認為是不太好的用法,但這不應該成為不支援內層自省的理由。 Python 3 因為丟棄了以前的未繫結方法(unbound method),而受到了侮辱性的傷害。 在 Python 2 中,給出以下定義: ```python class C: def f(): pass ``` 你可以從`C.f` 物件中獲得其所屬的類: ```python >>> C.f.i