Jak osiągnąć zmienne zmienne w Pythonie?
Oto szczegółowy manualny wpis, na przykład: Zmienne zmienne
Słyszałem, że jest to jednak zły pomysł i jest to luka w zabezpieczeniach Pythona. Czy to prawda?
python
variable-variables
Taryn
źródło
źródło
Odpowiedzi:
Aby to zrobić, możesz użyć słowników . Słowniki to magazyny kluczy i wartości.
Możesz użyć nazw kluczy zmiennych, aby uzyskać efekt zmiennych zmiennych bez ryzyka bezpieczeństwa.
W przypadkach, w których myślisz o zrobieniu czegoś takiego
lista może być bardziej odpowiednia niż dyktando. Lista reprezentuje uporządkowaną sekwencję obiektów z indeksami całkowitymi:
Dla zamówionych sekwencje, listy są bardziej wygodne niż dicts z kluczami całkowitych, ponieważ wykazy iteracji w celu wspierania indeksu, krojenie ,
append
i innych operacji, która wymaga zarządzania kluczami niewygodne z dict.źródło
Użyj wbudowanej
getattr
funkcji, aby uzyskać atrybut obiektu według nazwy. Zmodyfikuj nazwę zgodnie z potrzebami.źródło
To nie jest dobry pomysł. Jeśli uzyskujesz dostęp do zmiennej globalnej, możesz jej użyć
globals()
.Jeśli chcesz uzyskać dostęp do zmiennej w zasięgu lokalnym, możesz jej użyć
locals()
, ale nie możesz przypisać wartości do zwróconego dykta.Lepszym rozwiązaniem jest użycie
getattr
lub przechowywanie zmiennych w słowniku, a następnie dostęp do nich według nazwy.źródło
x = "foo"
ilocals()["x"] = "bar"
użycieprint x
daje wynikbar
dla Jython 2.5.2. Zostało to przetestowane za pomocą skryptu automatyzacji na żądanie w programie maximo .Ilekroć chcesz używać zmiennych zmiennych, prawdopodobnie lepiej jest użyć słownika. Więc zamiast pisać
ty piszesz
W ten sposób nie zastąpisz przypadkowo wcześniej istniejących zmiennych (co jest aspektem bezpieczeństwa) i możesz mieć różne „przestrzenie nazw”.
źródło
Nowi koderzy czasami piszą taki kod:
Koderowi pozostawia się stos nazwanych zmiennych, z wysiłkiem kodowania O ( m * n ), gdzie m to liczba nazwanych zmiennych, a n to liczba razy, do której grupa zmiennych musi być dostępna (w tym tworzenie ). Bardziej sprytny początkujący zauważa, że jedyną różnicą w każdej z tych linii jest liczba, która zmienia się w zależności od reguły, i decyduje się na użycie pętli. Utknęli jednak na tym, jak dynamicznie tworzyć te nazwy zmiennych i mogą spróbować czegoś takiego:
Wkrótce przekonują się, że to nie działa.
Jeśli program wymaga dowolnych „nazw zmiennych”, najlepszym wyborem jest słownik, jak wyjaśniono w innych odpowiedziach. Jeśli jednak po prostu próbujesz utworzyć wiele zmiennych i nie masz nic przeciwko odwoływaniu się do nich za pomocą sekwencji liczb całkowitych, prawdopodobnie szukasz
list
. Jest to szczególnie prawdziwe, jeśli dane są jednorodne, takie jak codzienne odczyty temperatury, cotygodniowe wyniki quizów lub siatka widżetów graficznych.Można to złożyć w następujący sposób:
To
list
może być również tworzone w jednej linii ze zrozumieniem:Wynik w obu przypadkach jest zapełniany
list
, z pierwszym elementem dostępnym za pomocąmy_calculator.buttons[0]
, następnym za pomocąmy_calculator.buttons[1]
itd. „Zmienna” nazwa zmiennej staje się nazwą,list
a do uzyskania dostępu używany jest zmienny identyfikator.Na koniec nie zapomnij o innych strukturach danych, takich jak
set
- jest to podobne do słownika, z tym wyjątkiem, że do każdej „nazwy” nie jest przypisana żadna wartość. Jeśli potrzebujesz po prostu „torby” przedmiotów, może to być świetny wybór. Zamiast czegoś takiego:Będziesz miał to:
Użyj a
list
do sekwencji podobnych obiektów, aset
do arbitralnie zamówionej torby przedmiotów lubdict
do torby nazw z powiązanymi wartościami.źródło
Zamiast słownika można również użyć
namedtuple
z modułu kolekcji, co ułatwia dostęp.Na przykład:
źródło
Jeśli nie chcesz używać żadnego obiektu, możesz nadal używać go
setattr()
w bieżącym module:źródło
__dict__
zmienną. Zastanawiam się, czy istnieje ogólny mechanizm dynamicznego tworzenia dowolnej zmiennej globalnej.globals()
mogę to zrobićSimpleNamespace
Klasy mogą być wykorzystywane do tworzenia nowych atrybutów zsetattr
lub podklasySimpleNamespace
i stworzyć własną funkcję dodawania nowych nazw atrybutów (zmienne).źródło
Odpowiadam na pytanie: jak uzyskać wartość zmiennej, biorąc pod uwagę jej nazwę w ciągu? który jest zamknięty jako duplikat z linkiem do tego pytania.
Jeśli zmienne w pytaniu są częścią obiektu (część klasy na przykład), a następnie kilka przydatnych funkcji, aby osiągnąć dokładnie, że są
hasattr
,getattr
isetattr
.Na przykład możesz mieć:
Następnie możesz zrobić:
źródło
Posługiwać się
globals()
W rzeczywistości możesz dynamicznie przypisywać zmienne do zakresu globalnego, na przykład, jeśli chcesz 10 zmiennych, do których można uzyskać dostęp w zakresie globalnym
i_1
,i_2
...i_10
:Spowoduje to przypisanie „a” do wszystkich tych 10 zmiennych, oczywiście można również dynamicznie zmieniać wartość. Wszystkie te zmienne są teraz dostępne, podobnie jak inne globalnie zadeklarowane zmienne:
źródło
Musisz użyć
globals()
wbudowanej metody, aby osiągnąć to zachowanie:źródło
Konsensus polega na użyciu do tego słownika - zobacz pozostałe odpowiedzi. Jest to dobry pomysł w większości przypadków, jednak wynika z tego wiele aspektów:
To powiedziawszy, zaimplementowałem klasę menedżera zmiennych zmiennych, która zawiera niektóre z powyższych pomysłów. Działa dla Pythona 2 i 3.
Użyłbyś takiej klasy :
Jeśli chcesz zezwolić na zastępowanie zmiennych tylko tego samego typu:
źródło
Próbowałem obu w Pythonie 3.7.3, możesz użyć globals () lub vars ()
Odniesienie:
https://www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable-name#post548936
źródło
Dowolny zestaw zmiennych można również zawinąć w klasę. Zmienne „Zmienne” można dodawać do instancji klasy podczas działania, bezpośrednio uzyskując dostęp do wbudowanego słownika poprzez atrybut __dict__.
Poniższy kod definiuje klasę Zmienne, która dodaje zmienne (w tym przypadku atrybuty) do swojego wystąpienia podczas budowy. Nazwy zmiennych są pobierane z określonej listy (która na przykład mogła zostać wygenerowana przez kod programu):
źródło