|
1 |
| - |
2 |
| -:mod:`__main__` --- Top-level script environment |
3 |
| -================================================ |
| 1 | +:mod:`__main__` --- Top-level code environment |
| 2 | +============================================== |
4 | 3 |
|
5 | 4 | .. module:: __main__
|
6 |
| - :synopsis: The environment where the top-level script is run. |
| 5 | + :synopsis: The environment where top-level code is run. Covers command-line |
| 6 | + interfaces, import-time behavior, and ``__name__ == '__main__'``. |
7 | 7 |
|
8 | 8 | --------------
|
9 | 9 |
|
10 |
| -``'__main__'`` is the name of the scope in which top-level code executes. |
11 |
| -A module's __name__ is set equal to ``'__main__'`` when read from |
12 |
| -standard input, a script, or from an interactive prompt. |
| 10 | +In Python, the special name ``__main__`` is used for two important constructs: |
| 11 | + |
| 12 | +1. the name of the top-level environment of the program, which can be |
| 13 | + checked using the ``__name__ == '__main__'`` expression; and |
| 14 | +2. the ``__main__.py`` file in Python packages. |
| 15 | + |
| 16 | +Both of these mechanisms are related to Python modules; how users interact with |
| 17 | +them and how they interact with each other. They are explained in detail |
| 18 | +below. If you're new to Python modules, see the tutorial section |
| 19 | +:ref:`tut-modules` for an introduction. |
| 20 | + |
| 21 | + |
| 22 | +.. _name_equals_main: |
| 23 | + |
| 24 | +``__name__ == '__main__'`` |
| 25 | +--------------------------- |
| 26 | + |
| 27 | +When a Python module or package is imported, ``__name__`` is set to the |
| 28 | +module's name. Usually, this is the name of the Python file itself without the |
| 29 | +``.py`` extension:: |
| 30 | + |
| 31 | + >>> import configparser |
| 32 | + >>> configparser.__name__ |
| 33 | + 'configparser' |
| 34 | + |
| 35 | +If the file is part of a package, ``__name__`` will also include the parent |
| 36 | +package's path:: |
| 37 | + |
| 38 | + >>> from concurrent.futures import process |
| 39 | + >>> process.__name__ |
| 40 | + 'concurrent.futures.process' |
| 41 | + |
| 42 | +However, if the module is executed in the top-level code environment, |
| 43 | +its ``__name__`` is set to the string ``'__main__'``. |
| 44 | + |
| 45 | +What is the "top-level code environment"? |
| 46 | +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
| 47 | + |
| 48 | +``__main__`` is the name of the environment where top-level code is run. |
| 49 | +"Top-level code" is the first user-specified Python module that starts running. |
| 50 | +It's "top-level" because it imports all other modules that the program needs. |
| 51 | +Sometimes "top-level code" is called an *entry point* to the application. |
| 52 | + |
| 53 | +The top-level code environment can be: |
| 54 | + |
| 55 | +* the scope of an interactive prompt:: |
| 56 | + |
| 57 | + >>> __name__ |
| 58 | + '__main__' |
| 59 | + |
| 60 | +* the Python module passed to the Python interpreter as a file argument: |
| 61 | + |
| 62 | + .. code-block:: shell-session |
| 63 | +
|
| 64 | + $ python3 helloworld.py |
| 65 | + Hello, world! |
| 66 | +
|
| 67 | +* the Python module or package passed to the Python interpreter with the |
| 68 | + :option:`-m` argument: |
| 69 | + |
| 70 | + .. code-block:: shell-session |
| 71 | +
|
| 72 | + $ python3 -m tarfile |
| 73 | + usage: tarfile.py [-h] [-v] (...) |
| 74 | +
|
| 75 | +* Python code read by the Python interpreter from standard input: |
| 76 | + |
| 77 | + .. code-block:: shell-session |
| 78 | +
|
| 79 | + $ echo "import this" | python3 |
| 80 | + The Zen of Python, by Tim Peters |
| 81 | +
|
| 82 | + Beautiful is better than ugly. |
| 83 | + Explicit is better than implicit. |
| 84 | + ... |
| 85 | +
|
| 86 | +* Python code passed to the Python interpreter with the :option:`-c` argument: |
| 87 | + |
| 88 | + .. code-block:: shell-session |
| 89 | +
|
| 90 | + $ python3 -c "import this" |
| 91 | + The Zen of Python, by Tim Peters |
| 92 | +
|
| 93 | + Beautiful is better than ugly. |
| 94 | + Explicit is better than implicit. |
| 95 | + ... |
| 96 | +
|
| 97 | +In each of these situations, the top-level module's ``__name__`` is set to |
| 98 | +``'__main__'``. |
| 99 | + |
| 100 | +As a result, a module can discover whether or not it is running in the |
| 101 | +top-level environment by checking its own ``__name__``, which allows a common |
| 102 | +idiom for conditionally executing code when the module is not initialized from |
| 103 | +an import statement:: |
| 104 | + |
| 105 | + if __name__ == '__main__': |
| 106 | + # Execute when the module is not initialized from an import statement. |
| 107 | + ... |
| 108 | + |
| 109 | +.. seealso:: |
| 110 | + |
| 111 | + For a more detailed look at how ``__name__`` is set in all situations, see |
| 112 | + the tutorial section :ref:`tut-modules`. |
| 113 | + |
| 114 | + |
| 115 | +Idiomatic Usage |
| 116 | +^^^^^^^^^^^^^^^ |
| 117 | + |
| 118 | +Some modules contain code that is intended for script use only, like parsing |
| 119 | +command-line arguments or fetching data from standard input. When a module |
| 120 | +like this were to be imported from a different module, for example to unit test |
| 121 | +it, the script code would unintentionally execute as well. |
| 122 | + |
| 123 | +This is where using the ``if __name__ == '__main__'`` code block comes in |
| 124 | +handy. Code within this block won't run unless the module is executed in the |
| 125 | +top-level environment. |
| 126 | + |
| 127 | +Putting as few statements as possible in the block below ``if __name___ == |
| 128 | +'__main__'`` can improve code clarity and correctness. Most often, a function |
| 129 | +named ``main`` encapsulates the program's primary behavior:: |
| 130 | + |
| 131 | + # echo.py |
| 132 | + |
| 133 | + import shlex |
| 134 | + import sys |
| 135 | + |
| 136 | + def echo(phrase: str) -> None: |
| 137 | + """A dummy wrapper around print.""" |
| 138 | + # for demonstration purposes, you can imagine that there is some |
| 139 | + # valuable and reusable logic inside this function |
| 140 | + print(phrase) |
| 141 | + |
| 142 | + def main() -> int: |
| 143 | + """Echo the input arguments to standard output""" |
| 144 | + phrase = shlex.join(sys.argv) |
| 145 | + echo(phrase) |
| 146 | + return 0 |
| 147 | + |
| 148 | + if __name__ == '__main__': |
| 149 | + sys.exit(main()) # next section explains the use of sys.exit |
| 150 | + |
| 151 | +Note that if the module didn't encapsulate code inside the ``main`` function |
| 152 | +but instead put it directly within the ``if __name__ == '__main__'`` block, |
| 153 | +the ``phrase`` variable would be global to the entire module. This is |
| 154 | +error-prone as other functions within the module could be unintentionally using |
| 155 | +the global variable instead of a local name. A ``main`` function solves this |
| 156 | +problem. |
| 157 | + |
| 158 | +Using a ``main`` function has the added benefit of the ``echo`` function itself |
| 159 | +being isolated and importable elsewhere. When ``echo.py`` is imported, the |
| 160 | +``echo`` and ``main`` functions will be defined, but neither of them will be |
| 161 | +called, because ``__name__ != '__main__'``. |
| 162 | + |
| 163 | + |
| 164 | +Packaging Considerations |
| 165 | +^^^^^^^^^^^^^^^^^^^^^^^^ |
| 166 | + |
| 167 | +``main`` functions are often used to create command-line tools by specifying |
| 168 | +them as entry points for console scripts. When this is done, |
| 169 | +`pip <https://pip.pypa.io/>`_ inserts the function call into a template script, |
| 170 | +where the return value of ``main`` is passed into :func:`sys.exit`. |
| 171 | +For example:: |
| 172 | + |
| 173 | + sys.exit(main()) |
| 174 | + |
| 175 | +Since the call to ``main`` is wrapped in :func:`sys.exit`, the expectation is |
| 176 | +that your function will return some value acceptable as an input to |
| 177 | +:func:`sys.exit`; typically, an integer or ``None`` (which is implicitly |
| 178 | +returned if your function does not have a return statement). |
| 179 | + |
| 180 | +By proactively following this convention ourselves, our module will have the |
| 181 | +same behavior when run directly (i.e. ``python3 echo.py``) as it will have if |
| 182 | +we later package it as a console script entry-point in a pip-installable |
| 183 | +package. |
| 184 | + |
| 185 | +In particular, be careful about returning strings from your ``main`` function. |
| 186 | +:func:`sys.exit` will interpret a string argument as a failure message, so |
| 187 | +your program will have an exit code of ``1``, indicating failure, and the |
| 188 | +string will be written to :data:`sys.stderr`. The ``echo.py`` example from |
| 189 | +earlier exemplifies using the ``sys.exit(main())`` convention. |
| 190 | + |
| 191 | +.. seealso:: |
| 192 | + |
| 193 | + `Python Packaging User Guide <https://packaging.python.org/>`_ |
| 194 | + contains a collection of tutorials and references on how to distribute and |
| 195 | + install Python packages with modern tools. |
| 196 | + |
| 197 | + |
| 198 | +``__main__.py`` in Python Packages |
| 199 | +---------------------------------- |
| 200 | + |
| 201 | +If you are not familiar with Python packages, see section :ref:`tut-packages` |
| 202 | +of the tutorial. Most commonly, the ``__main__.py`` file is used to provide |
| 203 | +a command-line interface for a package. Consider the following hypothetical |
| 204 | +package, "bandclass": |
| 205 | + |
| 206 | +.. code-block:: text |
| 207 | +
|
| 208 | + bandclass |
| 209 | + ├── __init__.py |
| 210 | + ├── __main__.py |
| 211 | + └── student.py |
| 212 | +
|
| 213 | +``__main__.py`` will be executed when the package itself is invoked |
| 214 | +directly from the command line using the :option:`-m` flag. For example: |
| 215 | + |
| 216 | +.. code-block:: shell-session |
| 217 | +
|
| 218 | + $ python3 -m bandclass |
| 219 | +
|
| 220 | +This command will cause ``__main__.py`` to run. How you utilize this mechanism |
| 221 | +will depend on the nature of the package you are writing, but in this |
| 222 | +hypothetical case, it might make sense to allow the teacher to search for |
| 223 | +students:: |
| 224 | + |
| 225 | + # bandclass/__main__.py |
| 226 | + |
| 227 | + import sys |
| 228 | + from .student import search_students |
| 229 | + |
| 230 | + student_name = sys.argv[2] if len(sys.argv) >= 2 else '' |
| 231 | + print(f'Found student: {search_students(student_name)}') |
| 232 | + |
| 233 | +Note that ``from .student import search_students`` is an example of a relative |
| 234 | +import. This import style must be used when referencing modules within a |
| 235 | +package. For more details, see :ref:`intra-package-references` in the |
| 236 | +:ref:`tut-modules` section of the tutorial. |
| 237 | + |
| 238 | +Idiomatic Usage |
| 239 | +^^^^^^^^^^^^^^^ |
| 240 | + |
| 241 | +The contents of ``__main__.py`` typically isn't fenced with |
| 242 | +``if __name__ == '__main__'`` blocks. Instead, those files are kept short, |
| 243 | +functions to execute from other modules. Those other modules can then be |
| 244 | +easily unit-tested and are properly reusable. |
| 245 | + |
| 246 | +If used, an ``if __name__ == '__main__'`` block will still work as expected |
| 247 | +for a ``__main__.py`` file within a package, because its ``__name__`` |
| 248 | +attribute will include the package's path if imported:: |
| 249 | + |
| 250 | + >>> import asyncio.__main__ |
| 251 | + >>> asyncio.__main__.__name__ |
| 252 | + 'asyncio.__main__' |
| 253 | + |
| 254 | +This won't work for ``__main__.py`` files in the root directory of a .zip file |
| 255 | +though. Hence, for consistency, minimal ``__main__.py`` like the :mod:`venv` |
| 256 | +one mentioned above are preferred. |
| 257 | + |
| 258 | +.. seealso:: |
| 259 | + |
| 260 | + See :mod:`venv` for an example of a package with a minimal ``__main__.py`` |
| 261 | + in the standard library. It doesn't contain a ``if __name__ == '__main__'`` |
| 262 | + block. You can invoke it with ``python3 -m venv [directory]``. |
| 263 | + |
| 264 | + See :mod:`runpy` for more details on the :option:`-m` flag to the |
| 265 | + interpreter executable. |
| 266 | + |
| 267 | + See :mod:`zipapp` for how to run applications packaged as *.zip* files. In |
| 268 | + this case Python looks for a ``__main__.py`` file in the root directory of |
| 269 | + the archive. |
| 270 | + |
| 271 | + |
| 272 | + |
| 273 | +``import __main__`` |
| 274 | +------------------- |
| 275 | + |
| 276 | +Regardless of which module a Python program was started with, other modules |
| 277 | +running within that same program can import the top-level environment's scope |
| 278 | +(:term:`namespace`) by importing the ``__main__`` module. This doesn't import |
| 279 | +a ``__main__.py`` file but rather whichever module that received the special |
| 280 | +name ``'__main__'``. |
| 281 | + |
| 282 | +Here is an example module that consumes the ``__main__`` namespace:: |
| 283 | + |
| 284 | + # namely.py |
| 285 | + |
| 286 | + import __main__ |
| 287 | + |
| 288 | + def did_user_define_their_name(): |
| 289 | + return 'my_name' in dir(__main__) |
| 290 | + |
| 291 | + def print_user_name(): |
| 292 | + if not did_user_define_their_name(): |
| 293 | + raise ValueError('Define the variable `my_name`!') |
| 294 | + |
| 295 | + if '__file__' in dir(__main__): |
| 296 | + print(__main__.my_name, "found in file", __main__.__file__) |
| 297 | + else: |
| 298 | + print(__main__.my_name) |
| 299 | + |
| 300 | +Example usage of this module could be as follows:: |
| 301 | + |
| 302 | + # start.py |
| 303 | + |
| 304 | + import sys |
| 305 | + |
| 306 | + from namely import print_user_name |
| 307 | + |
| 308 | + # my_name = "Dinsdale" |
| 309 | + |
| 310 | + def main(): |
| 311 | + try: |
| 312 | + print_user_name() |
| 313 | + except ValueError as ve: |
| 314 | + return str(ve) |
| 315 | + |
| 316 | + if __name__ == "__main__": |
| 317 | + sys.exit(main()) |
| 318 | + |
| 319 | +Now, if we started our program, the result would look like this: |
| 320 | + |
| 321 | +.. code-block:: shell-session |
| 322 | +
|
| 323 | + $ python3 start.py |
| 324 | + Define the variable `my_name`! |
| 325 | +
|
| 326 | +The exit code of the program would be 1, indicating an error. Uncommenting the |
| 327 | +line with ``my_name = "Dinsdale"`` fixes the program and now it exits with |
| 328 | +status code 0, indicating success: |
| 329 | + |
| 330 | +.. code-block:: shell-session |
| 331 | +
|
| 332 | + $ python3 start.py |
| 333 | + Dinsdale found in file /path/to/start.py |
| 334 | +
|
| 335 | +Note that importing ``__main__`` doesn't cause any issues with unintentionally |
| 336 | +running top-level code meant for script use which is put in the |
| 337 | +``if __name__ == "__main__"`` block of the ``start`` module. Why does this work? |
| 338 | + |
| 339 | +Python inserts an empty ``__main__`` module in :attr:`sys.modules` at |
| 340 | +interpreter startup, and populates it by running top-level code. In our example |
| 341 | +this is the ``start`` module which runs line by line and imports ``namely``. |
| 342 | +In turn, ``namely`` imports ``__main__`` (which is really ``start``). That's an |
| 343 | +import cycle! Fortunately, since the partially populated ``__main__`` |
| 344 | +module is present in :attr:`sys.modules`, Python passes that to ``namely``. |
| 345 | +See :ref:`Special considerations for __main__ <import-dunder-main>` in the |
| 346 | +import system's reference for details on how this works. |
| 347 | + |
| 348 | +The Python REPL is another example of a "top-level environment", so anything |
| 349 | +defined in the REPL becomes part of the ``__main__`` scope:: |
13 | 350 |
|
14 |
| -A module can discover whether or not it is running in the main scope by |
15 |
| -checking its own ``__name__``, which allows a common idiom for conditionally |
16 |
| -executing code in a module when it is run as a script or with ``python |
17 |
| --m`` but not when it is imported:: |
| 351 | + >>> import namely |
| 352 | + >>> namely.did_user_define_their_name() |
| 353 | + False |
| 354 | + >>> namely.print_user_name() |
| 355 | + Traceback (most recent call last): |
| 356 | + ... |
| 357 | + ValueError: Define the variable `my_name`! |
| 358 | + >>> my_name = 'Jabberwocky' |
| 359 | + >>> namely.did_user_define_their_name() |
| 360 | + True |
| 361 | + >>> namely.print_user_name() |
| 362 | + Jabberwocky |
18 | 363 |
|
19 |
| - if __name__ == "__main__": |
20 |
| - # execute only if run as a script |
21 |
| - main() |
| 364 | +Note that in this case the ``__main__`` scope doesn't contain a ``__file__`` |
| 365 | +attribute as it's interactive. |
22 | 366 |
|
23 |
| -For a package, the same effect can be achieved by including a |
24 |
| -``__main__.py`` module, the contents of which will be executed when the |
25 |
| -module is run with ``-m``. |
| 367 | +The ``__main__`` scope is used in the implementation of :mod:`pdb` and |
| 368 | +:mod:`rlcompleter`. |
0 commit comments