2013-04-01 14 views
11

Sto imparando come usare Qt con PyQt, e ho un QTabelView con un modello StandardItemModel ho compilato il modello con successo e ho collegato il segnale itemChanged a uno slot. Avevo l'piacerebbe pasticciare con qualsiasi oggetto viene restituito in IPython, quindi attualmente ho la linea:Posso ottenere un oggetto Python dal suo indirizzo di memoria?

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

che stampa

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

Nella sessione IPython è possibile ottenere l'oggetto che usa questo indirizzo di memoria? Non vedo nulla su Google, forse non ho la terminologia giusta?

+1

L'oggetto 'new_data' che si sta stampando è l'oggetto. Basta restituire o altrimenti archiviare quello invece di stamparlo. – BrenBarn

+0

Non è "impossibile" farlo, ma non è facile, e non è documentato che funzioni in nessuna circostanza, ed è generalmente una pessima idea. Se stai sperimentando come CPython funziona sotto le copertine, o eseguendo il debug del garbage collector, o qualcosa del genere, potrebbe valere la pena farlo, ma altrimenti, stai abbaiando dall'albero sbagliato, e la risposta di Raymond Hettinger è ciò che vuoi . – abarnert

risposta

8

Quasi certamente stai ponendo la domanda sbagliata e la risposta di Raymond Hettinger è quasi certamente ciò che desideri.

Qualcosa di simile potrebbe essere utile provare a scavare nell'interfaccia dell'interprete CPython per scopi di apprendimento o verificarlo per buchi di sicurezza o qualcosa del genere ... Ma anche allora, probabilmente stai meglio incorporando l'interprete Python in un programma e funzioni di scrittura che espongono tutto ciò che si desidera nell'interprete Python, o almeno scrivendo un modulo di estensione C che consente di manipolare oggetti CPython.

Ma, sulla remota possibilità che si ha realmente bisogno di fare questo ...

In primo luogo, non v'è alcun modo affidabile per ottenere anche l'indirizzo dal repr. La maggior parte degli oggetti con un'utile rappresentazione eval ti darà invece quella. Ad esempio, il repr di ('1', 1) è "('1', 1)", non <tuple at 0x10ed51908>. Inoltre, anche per gli oggetti che non hanno una rappresentazione utile, restituire <TYPE at ADDR> è solo una convenzione non dichiarata seguita da molti tipi (e un valore predefinito per le classi definite dall'utente), non qualcosa su cui poter fare affidamento.

Tuttavia, dal momento che presumibilmente interessa soltanto CPython, si può contare su id:

CPython dettaglio di implementazione: Questo è l'indirizzo dell'oggetto in memoria.

(Naturalmente se avete l'oggetto di chiamare id (o repr) in poi, non c'è bisogno di dereferenziarlo tramite puntatore, e se non si ha l'oggetto, probabilmente è stato garbage collection in modo non c'è niente da dereferenziare, ma forse lo hai ancora e non riesci a ricordare dove lo hai messo ...)

Avanti, cosa fai con questo indirizzo? Bene, Python non espone alcuna funzione per fare l'opposto di id. Ma lo Python C API è ben documentato e, se il tuo Python è costruito attorno a una libreria condivisa, è possibile accedere a tale API tramite ctypes, semplicemente caricandolo. Infatti, ctypes fornisce una variabile speciale che carica automaticamente la libreria condivisa corretta per chiamare l'API C su, ctypes.pythonapi.

In molto vecchie versioni di ctypes, potrebbe essere necessario trovare e caricare in modo esplicito, come pydll = ctypes.cdll.LoadLibrary('/usr/lib/libpython2.5.so') (Questo è per Linux con Python 2.5 installato in/usr/lib, la riga di comando, ovviamente, se uno qualsiasi di questi dettagli differiscono esatto sarà diverso.)

Ovviamente è molto più semplice arrestare l'interprete Python che fare qualcosa di utile, ma non è impossibile fare nulla di utile, e potresti divertirti a sperimentarlo.

7

È necessario mantenere un riferimento a un oggetto (ad esempio, assegnarlo a una variabile o memorizzarlo in un elenco).

Non esiste alcun supporto per la lingua per passare da un indirizzo oggetto direttamente a un oggetto (ad esempio pointer dereferencing).

Problemi correlati