Diciamo che ho un id di un oggetto Python, che ho recuperato facendo id(thing)
. Come faccio a trovare thing
di nuovo dal numero ID che mi è stato dato?Ottieni oggetto con id()?
risposta
probabilmente si vorrà prendere in considerazione la sua attuazione in un altro modo. Sei a conoscenza del modulo weakref?
(Modificato) Python weakref module consente di mantenere riferimenti, riferimenti di dizionario e proxy agli oggetti senza contare quei riferimenti nel contatore di riferimento. Sono come collegamenti simbolici.
A volte non è possibile creare un riferimento debole all'oggetto, ad esempio: TypeError: impossibile creare un riferimento debole all'oggetto "lxml.etree._Element" – darkk
È possibile utilizzare il modulo gc per ottenere tutti gli oggetti attualmente monitorati dal garbage collector Python.
import gc
def objects_by_id(id_):
for obj in gc.get_objects():
if id(obj) == id_:
return obj
raise Exception("No found")
Questo ha un problema di aliasing: un ID ottenuto in un punto arbitrario nel passato può ora fare riferimento a un oggetto diverso. – chaos
Fintanto che hai mantenuto un riferimento all'oggetto, ciò non accadrà. Allo stesso modo, questa è generalmente una cattiva idea. –
Sono d'accordo con molti degli altri commentatori: non farlo. Crea il tuo dizionario di oggetti. –
Risposta breve, non è possibile.
Risposta lunga, è possibile mantenere un dict per gli ID di mappatura agli oggetti, o cercare l'ID da ricerca esaustiva di gc.get_objects()
, ma questo creerà uno dei due problemi: o di riferimento del dict manterrà l'oggetto vivo e prevenire GC oppure (se si tratta di un dict WeakValue o si utilizza gc.get_objects()
) l'ID può essere deallocato e riutilizzato per un oggetto completamente diverso.
In sostanza, se si sta tentando di farlo, probabilmente è necessario fare qualcosa di diverso.
Ho intenzione di gettare via il riferimento di identificazione nell'oggetto '__del__', pensi che questo assicurerà che le cose non si rompano? –
+1: Accetto: non farlo. Crea semplicemente un dizionario appropriato di oggetti con le chiavi appropriate: sarai molto più felice. –
@ cool-RR: Sì, dovresti essere al sicuro con quello. – chaos
biblioteca eGenix mxTools fornisce una tale funzione, anche se contrassegnato come "esperto-only": mx.Tools.makeref(id)
Basta menzionare questo modulo per completezza. This code by Bill Bumgarner include un'estensione C per fare ciò che vuoi senza il loop su ogni oggetto esistente.
Il codice per la funzione è abbastanza semplice. Ogni oggetto Python è rappresentato in C da un puntatore a a PyObject
struct. Poiché id(x)
è solo l'indirizzo di memoria di questa struttura, possiamo recuperare l'oggetto Python trattando x
come puntatore a PyObject
, quindi chiamando Py_INCREF
per dire al garbage collector che stiamo creando un nuovo riferimento all'oggetto.
static PyObject *
di_di(PyObject *self, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "l:di", &obj))
return NULL;
Py_INCREF(obj);
return obj;
}
Se l'oggetto originale non esiste più, il risultato non è definito. Potrebbe bloccarsi, ma potrebbe anche restituire un riferimento a un nuovo oggetto che ha preso la posizione di quello vecchio in memoria.
Se l'oggetto è ancora lì, questo può essere fatto da ctypes
:
import ctypes
a = "hello world"
print ctypes.cast(id(a), ctypes.py_object).value
uscita:
hello world
Se non si sa se l'oggetto è ancora lì, questo è un ricetta per comportamento indefinito e crash strani o peggio, quindi state attenti.
Questo farà:
a = 0
id_a = id(a)
variables = {**locals(), **globals()}
for var in variables:
exec('var_id=id(%s)'%var)
if var_id == id_a:
exec('the_variable=%s'%var)
print(the_variable)
print(id(the_variable))
ma vi suggerisco l'attuazione di un modo più decente.
- 1. - Ottieni tweet con ID specifico
- 2. ArrayList Recupera oggetto con ID
- 3. Ottieni l'ultimo ID inserito Sequenza
- 4. Javascript: ottieni tutti gli elementi con id id [x]
- 5. Ottieni ID connessione PDO
- 6. MongoDB: Univocità ID oggetto
- 7. AngularJS - Ottieni dati per ID
- 8. Ottieni ID lavoratore in Celery
- 9. Ottieni ID risorsa da ImageView
- 10. Ottieni foglio Google per ID?
- 11. Richfaces - Ottieni elemento per ID
- 12. Ottieni istanza per istanza-id
- 13. Hibernate SQLQuery - Ottieni oggetto per nome
- 14. Ottieni un ID file univoco in Windows con Java?
- 15. Ottieni l'ultimo ID di inserimento con Oracle 11g utilizzando JDBC
- 16. Ottieni l'ultimo ID di inserimento con doctrine 2?
- 17. ID oggetto Java in jvm
- 18. Postgresql ID oggetto e tuple
- 19. Android - Trova oggetto per ID
- 20. Restangular - Get oggetto w/id, modificare oggetto, oggetto di aggiornamento
- 21. WP8/C#/SQLite: ottieni l'ultimo ID inserito?
- 22. Ottieni ruolo utente per ID Wordpress
- 23. Ottieni WordPress Post ID dal titolo post
- 24. Ottieni ID utente socket.io, passport, koa
- 25. Ottieni ID utente Facebook tramite indirizzo email
- 26. Ottieni ID bundle da un altro target
- 27. come ottengo un ID univoco per oggetto in Java?
- 28. Ottieni hwnd per id processo C++
- 29. Ottieni ID proprietà senza recupero record
- 30. Umbraco - Ottieni Node per ID programmaticamente
Sono curioso: perché vuoi farlo? Qual è il tuo obiettivo? –
@Craig McQueen: http: // stackoverflow.it/questions/1400295/python-class-for-pickle-and-copy-persistent-object –
Non ho potuto ritrovare la fonte di questo, ma ho pensato che ciò che viene restituito da id() è qualunque cosa la particolare distribuzione vuole deve essere. CPython ripristinato potrebbe, al momento, restituire un indirizzo simile alla memoria, ma altre distribuzioni potrebbero restituire diversi tipi di oggetto o interi che non sono puntatori di memoria. Sarebbe bello se esistesse una funzione incorporata per ottenere un oggetto da ciò che viene restituito da id(). Sebbene altri casi d'uso di persistenza siano difficili da immaginare. Anche se * variabile, come C sembra avere senso; Adoro Python per la mancanza di trucchi di punteggiatura come la maggior parte degli altri linguaggi. – DevPlayer