Warning
Most of the documentation was written prior to version 0.5 and needs to be updated. This work has now started for version 0.7 and we aim to have it completed before version 0.8 is available.
Why import *
?¶
Tip
As explained below, while I recommend to use import *
for easier interactions,
you might prefer the next best alternative which is to
import the Friendly
object by doing:
from friendly... import Friendly
In many pages of this documentation, you will see that I suggest to use
something like from friendly.X import *
.
This is often mentioned as being a bad practice, since it
“pollutes” the current namespace with various names whose origin become
difficult to trace.
If you have tried the Friendly console, or read the previous
pages in this documentation, you will have seen various useful
functions such as what()
, where()
, why()
, etc., which
can be used in an interactive mode. You can think of these
functions as useful additions to Python’s builtins, such as dir()
,
vars()
, etc.
These functions are meant to be used in interactive sessions.
Speaking of which, here are the names immediately available from the default namespace in a python interpreter:
>>> print(dir(__builtins__))
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException', 'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning', 'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError', 'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning', 'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False', 'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented', 'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration', 'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError', 'Warning', 'WindowsError', 'ZeroDivisionError', '_', '__build_class__', '__debug__', '__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__', 'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray', 'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits', 'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit', 'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property', 'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars', 'zip']
>>> len(dir(__builtins__))
154
Using import *
with friendly-traceback adds 19 names to the environment
so that they are immediately available in an interactive session:
>>> dir()
['Friendly', '__builtins__', 'back', 'explain', 'friendly_tb', 'get_include', 'get_lang', 'hint', 'history', 'python_tb', 'set_debug', 'set_formatter', 'set_include', 'set_lang', 'set_prompt', 'show_paths', 'what', 'where', 'why', 'www']
>>> len(dir()) # includes '__builtins__'
20
[Note: Friendly might add 2 to 4 additional names to select a specific theme.]
The usual suggested alternatives to importing everything are the following:
Import only what’s needed. For example:
from friendly.X import what, where, why
Import as a namespace; something like:
from friendly import X # or import friendly.X as Y
One problem with the first suggestion is that, as shown above,
friendly/friendly-traceback has quite a few
other functions that are potentially useful; nothing like the 154 names
shown above but still too many to type explicitly. So this might
require another import statement, from friendly.X import something_else
when wanting to use something_else
. Trying to import all the
possibly relevant functions by explicitly naming them
in a single import statement is not really practical.
Using the second alternative means that,
instead of simply writing why()
, one might have
to write something like X.why()
. A potential problem with
this second approach is that friendly.X
might contain many
other names, such as __path__
, __spec__
, etc., as well
as other functions which are meant to be used only within
module X
which are not useful but would show up when doing something like
dir(X)
or help(X)
.
When creating a special module friendly.X
for a specific
environment, such as friendly.idle
to be used with Python’s IDLE,
I define __all__
so that only the relevant objects are imported
when doing from friendly.X import *
.
Recommended alternative¶
If you do not wish to use import *
, I suggest instead the following:
from friendly.X import Friendly
# or
from friendly.X import Friendly as some_other_name
Friendly
is a special object which includes all the
potentially useful functions as methods to be used
during an interactive session.
By this, I mean that Friendly.why()
is equivalent
to writing why()
.
Friendly
is also imported if you do from friendly.X import *
.
As mentioned previously in Friendly object, Friendly
can be used to easily obtain a list of useful functions, without
needing to consult the documentation.