Nasza strona używa cookies. Korzystając ze strony, wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki. Rozumiem

Podgląd zmiennych w Pythonie - globals, locals, vars i dir

Yang Zhou Software Engineer
Sprawdź, jak przyjrzeć się zawartości globals, locals, vars i dir w Pythonie, aby szybciej zrozumieć kontekst pewnych akcji w kodzie.

Czytanie kodu dużych programów to niezwykle wymagające zadanie - nawet proste rzeczy mogą przyprawić o zawrót głowy. Na przykład:

  • Jak szybko wyszukać wszystkie nazwy zmiennych i wartości w danym skrypcie?
  • Jak sprawdzić wszystkie nazwy zmiennych i wartości w dużej funkcji lub klasie?
  • Jak odnaleźć listę obecnych atrybutów danego obiektu?


Możemy oczywiście szukać linijka po linijce, ucząc się nazw na pamięć lub spisywać je na kartce papieru. To jednak bardzo niepythonowe. 

Ciężej jest czytać kod, niż go napisać - Joel Spolsky, autor bloga programistycznego Joel on Software


Aby ułatwić sobie życie, możemy wykorzystać 4 funkcje Pythona, który posłużą nam do wyświetlania nazw zmiennych oraz wartości z jakiegoś zakresu. Nauczycie się tutaj jak z nich korzystać, a po czymś takim przeglądanie kodu będzie czystą przyjemnością. 


Funkcja 1: globals()

Jak sama nazwa wskazuje, globals() pokaże nam informacje dotyczące zakresu globalnego. Jeśli otworzymy konsolę i wpiszemy globals(), to zwrócony zostanie dict zawierający wszystkie nazwy i wartości zmiennych w zakresie globalnym.

>>> globals()
{'__name__': '__main__', '__doc__': None, ...}


(Niektóre dane wyjściowe w tym artykule zostały uproszczone przy pomocy … aby łatwiej się je czytało)

Jeśli dodamy jedną zmienną:

>>> Master = "Yang"
>>> globals
{'__name__': '__main__', '__doc__': None, ... ,'Master': 'Yang'}


Ponieważ funkcja globals() zwraca nam dict, to możemy nim manipulować w celu wydobycia tych dane, które nas interesują:

>>> [n for n in globals() if not n.startswith('__')]
['sys', 'Master']


Jak widać w powyższym przykładzie, użyliśmy wyrażenia listowego do wydobycia wszystkich nazw zmiennych i to bez dwóch najbardziej prawdopodobnych wyników. 


Funkcja 2: locals()

Funkcja locals() to bułka z masłem, o ile dobrze znamy globals(). Jak sama nazwa wskazuje, zwraca ona dict zawierający wszystkie nazwy lokalne oraz wartości. 

def top_developer():
    name = "Yang"
    country = "UK"
    print(locals())

top_developer()
# {'name': 'Yang', 'country': 'UK'}


Tak swoją drogą, to jeśli wywołamy locals() w zakresie globalnym, to rezultat będzie taki sam, jak w przypadku wywołania globals()

>>> globals() is locals()
True


Funkcja 3: vars()

Funkcja vars() zwróci __dict__, czyli słownik wykorzystywany do przechowywania atrybutów obiektu. Jej rezultat byłby taki sam, gdybyśmy wywołali __dict__ w sposób bezpośredni. 

class TopDeveloper:
    def __init__(self):
        self.name = "Yang"
        self.country = "UK"

me = TopDeveloper()
print(vars(me))
# {'name': 'Yang', 'country': 'UK'}
print(vars(me) is me.__dict__)
# True

Przykład użycia funkcji vars()


Nie każdy obiekt będzie posiadał __dict__, a więc metody vars() możemy używać tylko w niektórych częściach obiektów. 

year = 2020
vars(year)
# Traceback (most recent call last):
#   File "<input>", line 1, in <module>
# TypeError: vars() argument must have __dict__ attribute


Jak widać w powyższym przykładzie, typ obiektu int nie posiada __dict__, a więc użycie w nim vars() wyrzuci TypeError


Funkcja 4: dir()

Funkcja dir() pomaga nam pokazać listę nazw w ekwiwalentnym zasięgu. 

class TopDeveloper:
    def __init__(self):
        self.name = "Yang"
        self.country = "UK"
me = TopDeveloper()
print(dir(me))
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'country', 'name']


Tak naprawdę to dir wywołuje __dir__() w sposób wewnętrzny. 

class TopDeveloper:
    def __init__(self):
        self.name = "Yang"
        self.country = "UK"
    def __dir__(self):
        return [1, 2, 3]
me = TopDeveloper()
print(dir(me))
# [1, 2, 3]


Jak widać powyżej, jeśli zmienimy sposób działania __dir__, to rezultat dir() również się zmieni. 


Podsumowanie

Te 4 funkcje przydają się do wyświetlania nazw i wartości. Używa się ich w Pythonie, aby szybciej zobaczyć, co jest zdefiniowane w skryptach, obiektach itd. podczas przeglądania kodu danego programu. 


Oryginał tekstu w języku angielskim możesz przeczytać tutaj

Rozpocznij dyskusję

Lubisz dzielić się wiedzą i chcesz zostać autorem?

Podziel się wiedzą z 160 tysiącami naszych czytelników

Dowiedz się więcej