Załóżmy, że mam identyfikator obiektu Python, który pobrałem wykonując id(thing)
. Jak ponownie znaleźć thing
przez podany numer identyfikacyjny?Pobierz obiekt według id()?
Odpowiedz
Pewnie warto rozważyć wdrożenie to w inny sposób. Czy znasz moduł weakref?
(Edytowane) Python weakref module umożliwia zachowanie odniesień, odniesień słownikowych i serwerów proxy do obiektów bez liczenia odwołań w liczniku odwołań. Są jak dowiązania symboliczne.
Czasami nie można utworzyć słabego odwołania do obiektu, np .: TypeError: nie można utworzyć słabego odwołania do obiektu "lxml.etree._Element". – darkk
Możesz użyć modułu gc, aby pobrać wszystkie obiekty aktualnie śledzone przez moduł do zbierania śmieci Pythona.
import gc
def objects_by_id(id_):
for obj in gc.get_objects():
if id(obj) == id_:
return obj
raise Exception("No found")
To ma problem z aliasingiem: identyfikator uzyskany w dowolnym punkcie w przeszłości może teraz odnosić się do innego obiektu. – chaos
Dopóki zachowujesz odniesienie do obiektu, tak się nie stanie. Tak samo, to na ogół zły pomysł. –
Zgadzam się z wieloma innymi komentatorami: nie rób tego. Stwórz własny słownik przedmiotów. –
Krótka odpowiedź, nie możesz.
Długa odpowiedź, możesz zachować dyktat do mapowania identyfikatorów do obiektów lub sprawdzić ID poprzez wyczerpujące wyszukiwanie gc.get_objects()
, ale spowoduje to jeden z dwóch problemów: albo odniesienie do dyktatu utrzyma obiekt przy życiu i zapobiegnie GC lub (jeśli jest to dyktatura WeakValue lub używasz gc.get_objects()
), identyfikator może zostać zwolniony i ponownie użyty dla zupełnie innego obiektu.
Zasadniczo, jeśli próbujesz to zrobić, prawdopodobnie musisz zrobić coś inaczej.
Mam zamiar odrzucić referencję id w obiekcie '__del__', czy myślisz, że to się sprawi, że rzeczy się nie zepsują? –
+1: Zgadzam się: Nie rób tego. Po prostu stwórz odpowiedni słownik obiektów z odpowiednimi klawiszami - będziesz o wiele szczęśliwszy. –
@ cool-RR: Tak, powinieneś być z tym bezpieczny. – chaos
eGenix mxTools biblioteka daje taką funkcję, choć oznaczone jako „ekspert-only”: mx.Tools.makeref(id)
Wystarczy wspomnieć o tym module dla kompletności. This code by Bill Bumgarner zawiera rozszerzenie C, aby zrobić to, co chcesz, bez pętli w każdym istniejącym obiekcie.
Kod funkcji jest dość prosty. Każdy obiekt Pythona jest reprezentowany w C przez wskaźnik do a PyObject
struct. Ponieważto po prostu adres pamięci tej struktury, możemy pobrać obiekt Pythona przez potraktowanie x
jako wskaźnika do PyObject
, a następnie wywołanie Py_INCREF
w celu poinformowania śmieciarza, że tworzymy nowe odniesienie do obiektu.
static PyObject *
di_di(PyObject *self, PyObject *args)
{
PyObject *obj;
if (!PyArg_ParseTuple(args, "l:di", &obj))
return NULL;
Py_INCREF(obj);
return obj;
}
Jeśli oryginalny obiekt już nie istnieje, wynik jest niezdefiniowany. Może się zawiesić, ale może również zwrócić odniesienie do nowego obiektu, który zajął miejsce starego w pamięci.
Jeśli obiekt jest nadal istnieje, można to zrobić przez ctypes
:
import ctypes
a = "hello world"
print ctypes.cast(id(a), ctypes.py_object).value
wyjściowa:
hello world
Jeśli nie wiemy, czy obiekt jest nadal istnieje, to jest przepis na niezdefiniowane zachowanie i dziwne wypadki lub gorzej, więc bądź ostrożny.
to zrobi:
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))
ale sugeruję wdrożenie bardziej przyzwoity sposób.
- 1. Szyny Pobierz wiele według ID
- 2. Hibernacja: pobierz obiekt według identyfikatora
- 3. Pobierz obraz profilu użytkownika według Id
- 4. Pobierz obiekt według właściwości w Core Data
- 5. JavaScript Pobierz element według Id i ustaw wartość
- 6. CQL - pobierz rekordy według id i najnowszego znacznika czasu
- 7. Pobierz element wewnątrz elementu według klasy i ID - JavaScript
- 8. Javascript: pobierz cały obiekt, gdzie id jest podobny do log_XXXX
- 9. Pobierz ostatnią wstawioną id Sequelize
- 10. Użyj polecenia angle.element, aby uzyskać obiekt zakresu według $ ID
- 11. Pobierz pole według nazwy
- 12. Pobierz wątek według nazwy
- 13. Pobierz fragment widoku pojemnik id
- 14. AngularJS - Uzyskaj dane według ID
- 15. Usunąć model szkieletu według id?
- 16. Zmiana zawartości przęsła według id
- 17. Android: Pobierz obiekt
- 18. Pobierz instancję według identyfikatora wystąpienia
- 19. Pobierz zestaw według nazwy klasy
- 20. pobierz informacje z innej tabeli, gdzie id = id
- 21. Moduł Joomla, pobierz ID menu (ItemID) z ID artykułu
- 22. TypoScript: pobierz tytuł strony według nazwy strony
- 23. T-SQL - Selekcja według najbliższym terminie i pogrupowane według ID
- 24. jQuery - pobierz elementy formularza według identyfikatora kontenera
- 25. Twitter API - pobierz tweety z konkretnym id
- 26. Pobierz wyniki modelu Laravel na podstawie wielu ID
- 27. Pobierz klucz obiekt przy async.each
- 28. Obiekt Newtonsoft → Pobierz ciąg JSON
- 29. Jquery - Ustawianie opcji wyboru listy według ID
- 30. JSON: kluczowe elementy według id, czy nie?
Jestem ciekawy: dlaczego chcesz to zrobić? Jaki jest twój cel? –
@Craig McQueen: http: // stackoverflow.com/questions/1400295/python-class-for-pickle-and-copy-persistent-object –
Nie mogłem ponownie znaleźć źródła tego, ale myślałem, że to, co jest zwracane przez id(), jest tym, czego chce konkretna dystrybucja że jest to. Zmieniony CPython może teraz zwracać teraz adres podobny do pamięci, ale inne dystrybucje mogą zwracać różne typy obiektów lub int, które nie są wskaźnikami pamięci. Byłoby miło, gdyby istniała wbudowana funkcja do uzyskania obiektu przez to, co jest zwracane przez id(). Chociaż inne przypadki użycia uporczywości są trudne do wyobrażenia. Również, chociaż * zmienna, jak C wydaje się mieć sens; Uwielbiam Pythona za brak sztuczek interpunkcyjnych, jak większość innych języków. – DevPlayer