Chciałbym móc uzyskać nazwę zmiennej jako ciąg, ale nie wiem, czy Python ma tak wiele możliwości introspekcji. Coś jak:
>>> print(my_var.__name__)
'my_var'
Chcę to zrobić, ponieważ mam kilka zmiennych, które chciałbym przekształcić w słownik, np .:
bar = True
foo = False
>>> my_dict = dict(bar=bar, foo=foo)
>>> print my_dict
{'foo': False, 'bar': True}
Ale chciałbym coś bardziej automatycznego niż to.
Python ma locals()
i vars()
, więc myślę, że jest sposób.
Odpowiedzi:
Próbujesz to zrobić?
Przykład
źródło
print('x: ' + x)
pisaćmagic_print(x)
i mieć takie same dane wyjściowe bez dwukrotnego zapisu nazwy zmiennej.Jak powiedziałindind, nie jest to tak naprawdę czynność wykonywana w Pythonie - zmienne są w rzeczywistości odwzorowaniami nazw obiektów.
Jednakże , tu jest jeden sposób, aby spróbować zrobić:
źródło
True
), Wówczas może zostać zwrócona niezamierzona nazwa zmiennej.id(v) == id(a)
zamiastv is a
? Nie powiedzie się to w przypadku obiektów powiązanych z wieloma zmiennymi, takimi jak int, ciągi znaków i wszelkie podobnie zaimplementowane typy zdefiniowane przez użytkownika.v is a
byłby lepszy wybór. I tak, z pewnością niebezpieczne, biorąc pod uwagę wszystkie potencjalne pułapki, które mogą się pojawić! ;-)Bardzo chciałem to zrobić. Ten hack jest bardzo podobny do sugestii Rlotuna, ale jest to jedna linijka, co jest dla mnie ważne:
Python 3+
źródło
iteritems()
zastępuje sięitems()
spam = 1; blah = 1; blah_name = [ k for k,v in locals().items() if v is blah][0]; print(blah_name)
Wyjściaspam
spam = 1, blah = 1; assert spam is blah
. Rozwiązanie psuje się podczas porównywania pierwotnych typów danych.To jest hack. Nie będzie działać na wszystkich dystrybucjach implementacji Pythona (w szczególności tych, które nie mają
traceback.extract_stack
).Pamiętaj, że ten hack jest delikatny:
(wywołanie make_dict na 2 liniach) nie będzie działać.
Zamiast próbować wygenerować dykta z wartości
foo
ibar
byłoby znacznie bardziej Pythonic generowanie dykta z nazw zmiennych łańcuchowych'foo'
i'bar'
:źródło
print("a_very_long_name: {}'.format(a_very_long_name))
kogo to obchodzi!Nie jest to możliwe w Pythonie, który tak naprawdę nie ma „zmiennych”. Python ma nazwy i może istnieć więcej niż jedna nazwa dla tego samego obiektu.
źródło
Myślę, że mój problem pomoże zilustrować, dlaczego to pytanie jest przydatne, i może dać nieco więcej wglądu, jak na nie odpowiedzieć. Napisałem małą funkcję do szybkiego sprawdzania inline różnych zmiennych w moim kodzie. Zasadniczo zawiera nazwę zmiennej, typ danych, rozmiar i inne atrybuty, dzięki czemu mogę szybko wyłapać błędy, które popełniłem. Kod jest prosty:
Więc jeśli masz skomplikowaną sytuację słownik / lista / krotka, bardzo pomocne byłoby, aby interpreter zwrócił przypisaną nazwę zmiennej. Na przykład, oto dziwny słownik:
Nie jestem pewien, czy umieściłem to we właściwym miejscu, ale pomyślałem, że to może pomóc. Mam nadzieję, że tak.
źródło
myconnection
może wskazywać wartość logiczną w jednym punkcie, liczbę całkowitą w innym czasie i połączenie gniazda w innym punkcie podczas wykonywania kodu?Napisałem schludną, mało przydatną funkcję opartą na odpowiedzi na to pytanie. Kładę go tutaj, na wypadek, gdyby był użyteczny.
stosowanie:
źródło
Uważam, że jeśli masz już konkretną listę wartości, to sposób opisany przez @S. Lotts jest najlepszy; jednak sposób opisany poniżej działa dobrze, aby uzyskać wszystkie zmienne i klasy dodane w całym kodzie, BEZ potrzeby podawania nazwy zmiennej, choć można je podać, jeśli chcesz. Kod można rozszerzyć, aby wykluczyć klasy.
Wynik:
źródło
W Pythonie 3 jest to łatwe
to wydrukuje:
źródło
for v in locals()
.for v in list(locals()):
Python3. Użyj inspekcji, aby uchwycić wywoływaną lokalną przestrzeń nazw, a następnie skorzystaj z pomysłów przedstawionych tutaj. Może zwrócić więcej niż jedną odpowiedź, jak wskazano.
źródło
Oto funkcja, którą utworzyłem, aby odczytać nazwy zmiennych. Jest bardziej ogólny i może być używany w różnych aplikacjach:
Aby użyć go w określonym pytaniu:
źródło
Czytając wątek, zobaczyłem straszne tarcie. Łatwo jest dać złą odpowiedź, a następnie pozwolić komuś udzielić poprawnej odpowiedzi. W każdym razie oto, co znalazłem.
From: [effbot.org] ( http://effbot.org/zone/python-objects.htm#names )
Nazwy są nieco inne - nie są tak naprawdę właściwościami obiektu, a sam obiekt nie wie, jak się nazywa.
Obiekt może mieć dowolną liczbę nazw lub w ogóle żadnej nazwy.
Nazwy znajdują się w przestrzeniach nazw (takich jak przestrzeń nazw modułów, przestrzeń nazw instancji, lokalna przestrzeń nazw funkcji).
Uwaga: że mówi, że sam obiekt nie wie, jak się nazywa , więc taka była wskazówka. Obiekty Python nie są samoreferencyjne. Potem mówi: Nazwy żyją w przestrzeniach nazw . Mamy to w TCL / TK. Więc może moja odpowiedź pomoże (ale pomogła mi)
Na końcu listy znajduje się „jj”.
Przepisz kod jako:
Ten paskudny identyfikator kodu to nazwa zmiennej / object / what-you-pedantics-call-it.
Tak więc jest. Adres pamięci „jj” jest taki sam, gdy szukamy go bezpośrednio, podobnie jak podczas wyszukiwania słownika w globalnej przestrzeni nazw. Jestem pewien, że możesz to zrobić. Pamiętaj tylko, w której przestrzeni nazw znajduje się Twoja zmienna / obiekt / wypci.
CO BYŁO DO OKAZANIA.
źródło
print id(jj)
. Drugi po prostu sprawdza nazwę i można to zrobić łatwiejvars()
.Może zastanawiam się nad tym, ale ...
źródło
variable = 1 \n [k for k,v in locals().items() if id(variable) == id(v)] \n Out[14]: ['variable']
źródło
Przesłałem rozwiązanie do pypi . Jest to moduł definiujący odpowiednik funkcji C #
nameof
.Iteruje poprzez instrukcje kodu bajtowego dla ramki, do której jest wywoływany, i przekazuje do niego nazwy zmiennych / atrybutów. Nazwiska znajdują się w
.argrepr
zLOAD
instrukcją po nazwie funkcji.źródło
Napisałem paczkę czarów, aby solidnie wykonywać tego rodzaju magię. Możesz pisać:
źródło
Większość obiektów nie ma __name__ atrybutu . (Czy mają to klasy, funkcje i moduły; czy są jeszcze jakieś wbudowane typy, które je mają?)
Co jeszcze można się spodziewać za
print(my_var.__name__)
inne niżprint("my_var")
? Czy możesz po prostu użyć łańcucha bezpośrednio?Możesz „pokroić” dyktandę:
Alternatywnie:
źródło
some_func(var)
nic przeciwko wywoływaniu , więc starałem się wskazać, że nie jest bardzo dalekosome_func("var")
, a dictslice pozwala uzyskać mapowanie nazwy i wartości dla wielu zmiennych jednocześnie.Cóż, spotkałem się z tą samą potrzebą kilka dni temu i musiałem uzyskać nazwę zmiennej, która wskazywała na sam obiekt .
I dlaczego było to konieczne?
Krótko mówiąc, budowałem wtyczkę dla Mayi . Podstawowa wtyczka została zbudowana przy użyciu C ++, ale GUI jest pobierany przez Python (ponieważ nie wymaga dużego procesora). Ponieważ do tej pory nie wiem jak
return
wiele wartości z wtyczki oprócz domyślnejMStatus
, dlatego aby zaktualizować słownik w Pythonie, musiałem przekazać nazwę zmiennej, wskazując na obiekt implementujący GUI i który zawierał sam słownik do wtyczki, a następnie używałMGlobal::executePythonCommand()
do aktualizacji słownika z globalnego zasięgu Maya .Aby to zrobić, zrobiłem coś takiego:
Wiem, że nie jest to idealne rozwiązanie w
globals
wiele kluczy może wskazywać na ten sam obiekt, np .:i że podejście nie jest bezpieczne dla wątków. Popraw mnie, jeśli się mylę.
Przynajmniej to podejście rozwiązało mój problem, uzyskując nazwę dowolnej zmiennej w zasięgu globalnym, która wskazywała na obiekt sam i przekazała go do wtyczki, jako argument, do użycia wewnętrznego.
Próbowałem tego
int
(prymitywna klasa całkowita), ale problem polega na tym, że te prymitywne klasy nie są pomijane (proszę poprawić używaną terminologię techniczną, jeśli jest niepoprawna). Mógłbyś ponownie wdrożyć,int
a następnie zrobić,int = foo
alea = 3
nigdy nie będzie to obiektfoo
pierwotny. Aby przezwyciężyć to, musisza = foo(3)
iśća.name()
do pracy.źródło
W Pythonie 2.7 i nowszych dostępne jest również rozumienie słownika, co czyni go nieco krótszym. Jeśli to możliwe, użyłbym getattr zamiast eval (eval jest zły) jak w najwyższej odpowiedzi. Jaźń może być dowolnym przedmiotem, na który patrzysz w kontekście. Może to być obiekt lub locals = locals () itp.
źródło
Pracowałem nad podobnym problemem. @ S.Lott powiedział: „Jeśli masz listę zmiennych, to po co„ odkrywać ”ich nazwy?” A moja odpowiedź brzmi: czy można to zrobić i czy z jakiegoś powodu chcesz posortować zmienne według typu na listy. Tak czy inaczej, w moich badaniach natknąłem się na ten wątek, a moje rozwiązanie jest nieco rozszerzone i opiera się na rozwiązaniu @rlotun. Jedna inna rzecz, @unutbu powiedział: „Ten pomysł ma swoją wartość, ale zauważ, że jeśli dwie nazwy zmiennych odnoszą się do tej samej wartości (np. True), wówczas może zostać zwrócona niezamierzona nazwa zmiennej”. W tym ćwiczeniu to prawda więc do czynienia z nim za pomocą wyrażeń listowych podobny do tego dla każdej możliwości:
isClass = [i for i in isClass if i != 'item']
. Bez tego „item” pojawiłby się na każdej liście.źródło
pi = pie
do swojego kodu, uzyskasz dodatkowy wpis naisFloat
liście. Jeśli dodałeśtuple_1[0]
do swojejmixedDataTypes
listy, nie znajdzie się dla niej nazwy, mimo że „jeden” znajduje się w kodzie dwa razy (chociaż dzięki internowaniu łańcucha, oba będą odwołaniami do tego samego obiektu).pi
ie
jako zmiennych powodowało niechciane dane wyjściowe, a to dlatego, że oba są częściąmath
biblioteki. Dla mnie było to tylko ćwiczenie, aby sprawdzić, czy da się to zrobić, nawet jeśli efekt końcowy nie jest idealny. W mojej nauce tego języka przeglądanie książek idzie tylko tak daleko. Moim zdaniem, jeśli naprawdę chcesz nauczyć się języka, musisz zagrać „co jeśli” i zobaczyć, co wymyślisz.możesz użyć easydict
inny przykład:
źródło
W Python3 ta funkcja otrzyma najbardziej zewnętrzną nazwę ze stosu:
Jest przydatny w dowolnym miejscu kodu. Przemierza odwrócony stos w poszukiwaniu pierwszego dopasowania.
źródło
Chociaż jest to prawdopodobnie okropny pomysł, jest zgodny z odpowiedzią rlotun, ale częściej zwraca poprawny wynik.
Nazywasz to tak:
źródło
powinien dostać listę, a następnie wrócić
źródło
Nie zwróci nazwy zmiennej, ale możesz łatwo utworzyć słownik ze zmiennej globalnej.
źródło
Z
python-varname
łatwością możesz to zrobić:pip install python-varname
Oświadczenie: Jestem autorem tej biblioteki zmiennych python-varname.
źródło
w ten sposób uzyskaj zmienną dla nazwy „a” lub „b”.
źródło