2013-04-01 90 views
11

我正在學習如何在PyQt中使用Qt,並且我有一個QTabelView和一個StandardItemModel,我已經成功地爲模型填充了這個模型,並將itemChanged信號連接到一個插槽。我倒是我ð想與任何對象IPython中返回勾搭,所以目前我行:我可以從內存地址獲取python對象嗎?

def itemChangedSlot(epw, item): 
    new_data = item.data() 
    print new_data 
    print item 

它打印

<PyQt4.QtGui.QStandardItem object at 0x07C5F930> 
<PyQt4.QtCore.QVariant object at 0x07D331F0> 

在IPython的會話是有可能得到使用這個內存地址的對象?我在谷歌上沒有看到任何東西,也許我沒有我的術語是對的?

+1

您正在打印的對象'new_data'是對象。只需返回或以其他方式存儲,而不是打印它。 – BrenBarn

+0

這樣做不是不可能的,但這並不容易,而且在任何情況下都沒有文件記錄,所以這通常是一個非常糟糕的主意。如果你正在試驗CPython如何工作,或者調試垃圾收集器或類似的東西,那麼這可能是值得的,但否則,你會吼出錯誤的樹,Raymond Hettinger的答案就是你想要的。 – abarnert

回答

8

你幾乎肯定會提出錯誤的問題,Raymond Hettinger的回答幾乎肯定是你真正想要的。

像這樣的東西可能是有用的,試圖挖掘CPython解釋器的內部用於學習目的或審覈它的安全漏洞或什麼......但即使如此,你可能更好的將Python解釋器嵌入到程序中,編寫函數,將任何你想要的東西公開到Python解釋器中,或者至少編寫一個C擴展模塊,讓你操作CPython對象。

但是,上關的機會,你真的需要做到這一點...

首先,有沒有可靠的辦法,甚至您可以通過repr地址。大多數具有有用eval可選表示的對象都會替代您。例如,('1', 1)的編號是"('1', 1)",而不是<tuple at 0x10ed51908>。此外,即使對於沒有有用表示的對象,返回<TYPE at ADDR>也只是許多類型遵循的未聲明約定(以及用戶定義類的默認約定),而不是您可以依賴的約定。

但是,因爲你可能只關心CPython中,你可以依靠id

CPython的實現細節:這是在內存中對象的地址。

(當然,如果你有對象上調用id(或repr),你不通過指針需要取消對它的引用,如果您還沒有對象,它可能被垃圾回收等等沒有東西可以解引用,但也許你仍然擁有它,只是不記得你把它放在哪裏......)

接下來,你對這個地址做了什麼?那麼,Python不會公開任何與id相反的功能。但是Python C API有很好的文檔記錄 - 如果您的Python是圍繞共享庫構建的,那麼只需加載它即可通過ctypes訪問該C API。實際上,​​提供了一個特殊的變量,可以自動加載正確的共享庫來調用C API,ctypes.pythonapi。(這適用於Python 2.5安裝到/ usr/lib中的linux;顯然,如果這些細節中的任何一個有所不同,則確切的命令行將會有所不同)。

當然,破解Python解釋器比做任何有用的事情要容易得多,但做任何有用的事情都不是不可能的,而且你可能對試驗它有樂趣。

7

您需要保留對對象的引用(即將其分配給變量或將其存儲在列表中)。

從對象地址直接轉到對象(即pointer dereferencing)沒有語言支持。

相關問題