Utilities to help populate a modules'
__all__ attribute
3 bonuses 7 hints 21 solved 4 reviews
I'd like you to make utilities to help module authors populate their module's __all__ attribute.
The __all__ attribute controls what names are imported when we use a wild card import: from my_module import *.
The first utility in your dunder_all module should be called auto_all.
Your auto_all callable should accept a dictionary of all global variables in a module and should return a list of names to include in __all__.
The names included by auto_all should be variables pointing to functions and classes that were created within the current module (see the hints if you need help figuring out what module an object was made in).
But underscore-prefixed names (i.e. _something) should not be included (that's a convention used for private variables).
Given this (overly complicated) greet.py file:
from dunder_all import auto_all
GREETING = "Hello"
class _Greeter:
def __init__(self, greeting="Hello"):
self.greeting = greeting
def __call__(self, name="world"):
print(self.greeting, name)
def _greet(greeting, name):
_Greeter(greeting)(name)
def greet(name):
_greet(GREETING, name)
__all__ = auto_all(globals())
Using a wild card import imports just the greet function:
>>> dir()
['__builtins__']
>>> from greet import *
>>> dir()
['__builtins__', 'greet']
The _Greeter class and _greet function aren't included because their names start with an _ prefix.
The GREETING string isn't included because we can't determine which module a string was created in at runtime (we can figure that out only for functions and classes).
If we use auto_all when defining this more_math.py module:
from math import sqrt
from dunder_all import auto_all
root5 = sqrt(5)
phi = (1 + root5)/2 # The golden ratio
def nth_lucas(n):
"""Return the n-th Lucas number."""
return round(phi**n + (-1/phi)**n)
def sum_of_squares(*numbers):
return sum(n**2 for n in numbers)
__all__ = auto_all(globals())
We'll see that only nth_lucas and sum_of_squares are included in wild card imports (the sqrt function was not included):
>>> from more_math import *
>>> dir()
['__builtins__', 'greet', 'nth_lucas', 'sum_of_squares']
Want to solve this one?
Hi, I’m Trey, and I teach Python. Give this one a go, then I’ll show you how I’d solve it.