As your program gets longer, you will need to sort it as a file or split it into several files
Python has a way to put definitions in a file and use them in a script or in an interactive instance of the interpreter. Such a file is called a module.
The file name is the module name with the suffix
.py
appended.Within a module, the module’s name (as a string) is available as the value of the global variable
__name__
.Whenever the Python interpreter reads a source file, it does two things:
- it sets a few special variables like
__name__
, and then - it executes all of the code found in the file.
The
import
statement do the same, so it will result in code executing!!!, see more at stackoverflow and geeksforgeeks1
2
3
4
5
6
7
8# source of ptest.py
print('ptest is imported')
def badcode():
print('badcode is executed')
print('real bad code should be like this.')
print(__name__) # __name__ is __main__ when call by interpreter directly, otherwise the name of the module.1
2
3
4# source of callptest.py
import ptest
print(__name__)1
2
3
4
5
6
7
8
9$ python3 ptest.py
ptest is imported
real bad code should be like this.
__main__
$ python3 callptest.py
ptest is imported
real bad code should be like this.
ptest
__main__- it sets a few special variables like
the
import
statement does not enter the names of the functions defined inModuleName
directly in the current symbol table; it only enters the module nameModuleName
there. Using the module name you can access the functions.1
2
3
4
5
6
7
8
9
10import ptest
ptest is imported
real bad code should be like this.
ptest
badcode()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'badcode' is not defined
ptest.badcode()
badcode is executed6.1. More on Modules
import statement will execute the codes in a module only the first time it is encountered, this prevent multiple importing.
1
2
3
4
5
6
7import callptest
ptest is imported
real bad code should be like this.
ptest
callptest
import ptest1
2
3
4
5
6import ptest
ptest is imported
real bad code should be like this.
ptest
import callptest
callptestEach module has its own private symbol table, which is used as the global symbol table by all functions defined in the module. This avoid name collision.
- to import it again, check importlib.reload(), result in code executing!!!
1
2
3
4
5
6
7def badcode():
'badcode in main') print(
badcode()
badcode in main
ptest.badcode()
badcode is executed1
2
3# it can be referred ptest.badcode = badcode
ptest.badcode()
badcode in mainOther variants of import
from ModuleName import FunctionName , ItemName
this operation does not import the ModuleName
from ModuleName import *
this operation does not import names begin with
_
, it is poorly readable and may mask names defined before, frowned upon.
use
as
to make an alias1
2
3
4
5
6
7
8
9
10import ptest as p
ptest is imported
real bad code should be like this.
ptest
ptest
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ptest' is not defined
p
<module 'ptest' from '/Users/rubbish/test/ptest.py'>1
2
3
4
5
6
7
8
9
10
11
12
13
14from ptest import badcode as bc
ptest is imported
real bad code should be like this.
ptest
ptest
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'ptest' is not defined
badcode
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'badcode' is not defined
bc
<function badcode at 0x107325ca0>6.1.1. Executing modules as scripts
make your modules both executable and importable
1 | # add this condition |
6.1.2. The Module Search Path
built-in module
a list of directories given by the variable sys.path. It is initialized by:
2.1 The directory containing the input script (or the current directory when no file is specified).
2.2 PYTHONPATH (a list of directory names, with the same syntax as the shell variable
PATH
).2.3 The installation-dependent default.
end
the directory containing the symlink is NOT added to the module search path.
The
sys.path
list is editable, you can add the path manually.1
2
3
4
5
6
7import desk
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'desk'
'/Users/username/Desktop') sys.path.append(
import desk
Desktop!!!If you run the source file as a script, the directory containing the script being run is placed at the beginning of the search path, ahead of the standard library path. This means that scripts in that directory will be loaded instead of modules of the same name in the library directory. This is an error unless the replacement is intended.
The subdirectories are NOT included!!! (If you want to include subdirectories, make it a package)
1
2
3
4
5
6
7
8
9
10
11
12
13/Users/username/test
├── mode
└── ptest.py
'/Users/username/test') dirs.append(
import ptest
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'ptest'
'/Users/username/test/mode') dirs.append(
import ptest
ptest is imported
real bad code should be like this.
ptest6.1.3. “Compiled” Python files
To speed up loading modules, Python caches the compiled version of each module in the
__pycache__
directory under the namemodule.version.pyc
1 | $ ls __pycache__ |
Python checks the modification date of the source against the compiled version to see if it’s out of date and needs to be recompiled.
the compiled modules are platform-independent
Python does not check the date of the cache in two circumstances
- Command-line loaded modules
- no source module (To support a non-source (compiled only) distribution, the compiled module must be in the source directory, and there must not be a source module.)
compiled modules only loaded faster than source file
The module compileall can create .pyc files for all modules in a directory.
compile specified files
1
2
3$ python3 -m py_compile ptest.py
$ ls __pycache__/
ptest.cpython-39.pyccompile with optimizations
1
2
3$ python3 -O -m py_compile ptest.py
$ ls __pycache__/
ptest.cpython-39.opt-1.pyc1
2
3
4-O : remove assert and __debug__-dependent statements; add .opt-1 before
.pyc extension; also PYTHONOPTIMIZE=x
-OO : do -O changes and also discard docstrings; add .opt-2 before
.pyc extensionsee more in PEP 3147.
6.2. Standard Modules
The set of such modules is a configuration option which also depends on the underlying platform.(like
winreg
only available on Windows)sys.ps1
andsys.ps2
define the primary and the secondary prompt. These two variables are only defined if the interpreter is in interactive mode.1
2
3
4
5
6
7
8
9
10
11
12
13import sys
sys.ps1
'>>> '
sys.ps2
'... '
'$$$' sys.ps1 =
$$$
$$$
$$$
$$$sys.ps1 = '😀'
😀
😀
😀6.3. The
dir()
FunctionThe built-in function dir() is used to find out which names a module defines. It returns a sorted list of strings.
Without arguments, dir() lists the names you have defined currently
1 | dir() |
Note that it lists all types of names: variables, modules, functions, etc, with built-in things excluded.
you can get builtins by
builtin
1
2import builtins
dir(builtins)6.4. Packages
Packages are a way of structuring Python’s module namespace by using “dotted module names”.
Or you can take it as a collection of modules.
the use of dotted module names saves the authors of multi-module packages from having to worry about each other’s module names.
When importing the package, Python searches through the directories on
sys.path
looking for the package subdirectory.The
__init__.py
files are required to make Python treat directories containing the file as packages.__init__.py
can just be an empty file, but it can also execute initialization code for the package or set the__all__
variableUsers of the package can import individual modules from the package
1
2
3import sound.effects.echo # This loads the submodule sound.effects.echo.
# or
from sound.effects import echothe item can be either a submodule (or subpackage) of the package, or some other name defined in the package, like a function, class or variable.
The
import
statement first tests whether the item is defined in the package; if not, it assumes it is a module and attempts to load it.when using syntax like
import item.subitem.subsubitem
, each item except for the last must be a package; the last item can be a module or a package but can’t be a class or function or variable defined in the previous item.1
2
3
4
5
6
7
8import mypkg.pkg.greet.tell # wrong
Hello, I am a package
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'mypkg.pkg.greet.tell'; 'mypkg.pkg.greet' is not a package
from mypkg.pkg.greet import tell # right
tell()
hello6.4.1. Importing * From a Package
if a package’s
__init__.py
code defines a list named__all__
, it is taken to be the list of module names that should be imported whenfrom package import *
is encountered.
- If
__all__
is not defined, the statementfrom sound.effects import *
does not import all submodules from the packagesound.effects
into the current namespace; it only ensures that the packagesound.effects
has been imported (possibly running any initialization code in__init__.py
) - then imports whatever names are defined in the package
from package import specific_submodule
is the recommended way
6.4.2. Intra-package References
use leading dots to make relatively import
1 | from . import ModuleName # from current pkg import a module in the same pkg |
- Note that relative imports are based on the name of the current module.
- modules intended for use as the main module of a Python application must always use absolute imports.
6.4.3. Packages in Multiple Directories
__path__
is a special variable, a list containing the name of the directory holding the package’s__init__.py
before the code in that file is executed.it can be used to extend the set of modules found in a package.