9.8. Idiom Dir

  • dir([object])

  • If called without an argument, return the names in the current scope

  • Else, return an alphabetized list of names comprising (some of) the attributes of the given object, and of attributes reachable from it

9.8.1. SetUp

>>> class User:
...     def __init__(self, username, password):
...         self.username = username
...         self.password = password
...
...     def login(self):
...         return 'logged-in'
...
...     def logout(self):
...         return 'logged-out'

9.8.2. Class

>>> dir(User)
['__class__', '__delattr__', '__dict__', '__dir__',
 '__doc__', '__eq__', '__firstlineno__', '__format__',
 '__ge__', '__getattribute__', '__getstate__', '__gt__',
 '__hash__', '__init__', '__init_subclass__', '__le__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
 '__static_attributes__', '__str__', '__subclasshook__',
 '__weakref__', 'login', 'logout']

9.8.3. Instance

>>> alice = User('alice', 'secret')
>>>
>>> dir(alice)
['__class__', '__delattr__', '__dict__', '__dir__',
 '__doc__', '__eq__', '__firstlineno__', '__format__',
 '__ge__', '__getattribute__', '__getstate__', '__gt__',
 '__hash__', '__init__', '__init_subclass__', '__le__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
 '__static_attributes__', '__str__', '__subclasshook__',
 '__weakref__', 'login', 'logout', 'password', 'username']

9.8.4. Dir vs Vars

  • Function vars() returns variables only

  • Function dir() returns variables and methods

>>> alice = User('alice', 'secret')
>>>
>>> vars(alice)
{'username': 'alice', 'password': 'secret'}
>>>
>>> dir(alice)
['__class__', '__delattr__', '__dict__', '__dir__',
 '__doc__', '__eq__', '__firstlineno__', '__format__',
 '__ge__', '__getattribute__', '__getstate__', '__gt__',
 '__hash__', '__init__', '__init_subclass__', '__le__',
 '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
 '__static_attributes__', '__str__', '__subclasshook__',
 '__weakref__', 'login', 'logout', 'password', 'username']

9.8.5. Public Attributes

>>> [attrname
...  for attrname in dir(alice)
...  if not attrname.startswith('_')]
...
['login', 'logout', 'password', 'username']

9.8.6. Public Methods

>>> [attrname
...  for attrname in dir(alice)
...  if not attrname.startswith('_')
...  and callable(getattr(alice, attrname))]
...
['login', 'logout']

9.8.7. Public Variables

>>> [attrname
...  for attrname in dir(alice)
...  if not attrname.startswith('_')
...  and not callable(getattr(alice, attrname))]
...
['password', 'username']

Rationale:

>>> result = getattr(alice, 'username')
>>> result
'alice'
>>> result = getattr(alice, 'login')
>>> result()
'logged-in'

9.8.8. Assignments

# %% About
# - Name: Idiom Dir Class
# - Difficulty: easy
# - Lines: 1
# - Minutes: 2

# %% License
# - Copyright 2025, Matt Harasymczuk <matt@python3.info>
# - This code can be used only for learning by humans
# - This code cannot be used for teaching others
# - This code cannot be used for teaching LLMs and AI algorithms
# - This code cannot be used in commercial or proprietary products
# - This code cannot be distributed in any form
# - This code cannot be changed in any form outside of training course
# - This code cannot have its license changed
# - If you use this code in your product, you must open-source it under GPLv2
# - Exception can be granted only by the author

# %% English
# 1. Get list of attributes of `User` class
# 2. Define `result: list` with the result
# 3. Run doctests - all must succeed

# %% Polish
# 1. Pobierz listę atrybutów klasy `User`
# 2. Zdefiniuj `result: list` z wynikiem
# 3. Uruchom doctesty - wszystkie muszą się powieść

# %% Example
# >>> result
# ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
#  '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__',
#  '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__',
#  '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
#  '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__',
#  '__str__', '__subclasshook__', '__weakref__', 'login', 'logout']

# %% Doctests
"""
>>> import sys; sys.tracebacklimit = 0
>>> assert sys.version_info >= (3, 9), \
'Python 3.9+ required'

>>> from pprint import pprint
>>> from inspect import isclass

>>> assert isclass(User)

>>> assert '__init__' in result
>>> assert 'login' in result
>>> assert 'logout' in result

>>> result  # doctest: +NORMALIZE_WHITESPACE
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__',
 '__eq__', '__firstlineno__', '__format__', '__ge__', '__getattribute__',
 '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__',
 '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__',
 '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__static_attributes__',
 '__str__', '__subclasshook__', '__weakref__', 'login', 'logout']
"""

# %% Run
# - PyCharm: right-click in the editor and `Run Doctest in ...`
# - PyCharm: keyboard shortcut `Control + Shift + F10`
# - Terminal: `python -m doctest -f -v myfile.py`

# %% Imports

# %% Types
result: dict[str, str|bool]

# %% Data
class User:
    def __init__(self, username, password):
        self.username = username
        self.password = password
        self.authenticated = False

    def login(self):
        self.authenticated = True

    def logout(self):
        self.authenticated = False

# %% Result
result = ...