Python Getting Started Tutorial | Python Modules and Packages

Python modules

In the previous chapters, we basically used the Python interpreter for programming. If you exit and then enter the Python interpreter, all the methods and variables you defined will disappear.

For this purpose, Python provides a way to store these definitions in a file for use by some scripts or interactive interpreter instances. This file is called a module.

A module is a file that contains all the functions and variables you define, and its suffix is ​​.py. Modules can be imported by other programs to use functions and other functions in the module. This is also how to use the python standard library.

Below is an example using modules from the python standard library.

#!/usr/bin/python3
# 文件名: using_sys.py
 
import sys
 
print('命令行参数如下:')
for i in sys.argv:
   print(i)
 
print('\n\nPython 路径为:', sys.path, '\n')

The execution result is as follows:

$ python using_sys.py Parameter 1 Parameter 2
The command line parameters are as follows:
using_sys.py
Parameter 1
Parameter 2


The Python path is: ['/root', '/usr/lib/python3.4', '/usr/lib/python3. 4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3 /dist-packages']

  • import sys introduces the sys.py module in the python standard library; this is the way to introduce a module.
  • sys.argv is a list containing command line arguments.
  • sys.path contains a list of paths where the Python interpreter automatically looks for required modules.

import statement

If you want to use a Python source file, just execute the import statement in another source file. The syntax is as follows:

import module1, module2,… moduleN

Here, "module" is the name of the Python source file you want to import (no .py suffix required). After importing, you can use any function or class in this module by prefixing the call with the module name.
When the interpreter encounters an import statement, the module will be imported if it is in the current search path.

The search path is a list of all directories that the interpreter will search first. If you want to import the support module, you need to put the command at the top of the script:

#!/usr/bin/python3
# Filename: support.py
 
def print_func( par ):
    print ("Hello : ", par)
    return

test.py introduces the support module:

#!/usr/bin/python3
# Filename: test.py
 
# 导入模块
import support
 
# 现在可以调用模块里包含的函数了
support.print_func("Tarzan")

The output of the above example is:

C:\Users\Lenovo\Desktop>python test.py
Hello : Tarzan

A module will only be imported once, no matter how many times you execute the import. This prevents imported modules from being executed over and over again.

When we use the import statement, how does the Python interpreter find the corresponding file?

This involves Python's search path, which consists of a series of directory names, and the Python interpreter looks for imported modules from these directories in turn.

This looks a lot like environment variables. In fact, the search path can also be determined by defining environment variables.

The search path is determined when Python is compiled or installed, and should also be modified when installing new libraries. The search path is stored in the path variable in the sys module. To do a simple experiment, enter the following code in the interactive interpreter:

>>> import sys
>>> sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
>>> 

The output of sys.path is a list, the first item of which is the empty string '', which represents the current directory (if it is printed from a script, you can see more clearly which directory it is), that is, when we execute the python interpreter Directory (for scripts, this is the directory where the script to be run is located).

Therefore, if, like me, there is a file with the same name as the module to be imported in the current directory, the module to be imported will be blocked.

After understanding the concept of search path, you can modify sys.path in the script to introduce some modules that are not in the search path.

Now, create a fibo.py file in the current directory of the interpreter or a directory in sys.path. The code is as follows:

# 斐波那契(fibonacci)数列模块
 
def fib(n):    # 定义到 n 的斐波那契数列
    a, b = 0, 1
    while b < n:
        print(b, end=' ')
        a, b = b, a+b
    print()
 
def fib2(n): # 返回到 n 的斐波那契数列
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

Then enter the Python interpreter and import this module using the following command:

import fibo

This does not write the function name directly defined in fibo into the current symbol table, but only writes the name of the module fibo there.

Functions can be accessed using the module name:

>>>fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
>>> fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
>>> fibo.__name__
'fibo'

If you plan to use a function frequently, you can give it a local name:


>>> fib = fibo.fib
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

from … import statement

Python's from statement allows you to import a specified part from the module into the current namespace. The syntax is as follows:

from module_name import name1, name2, … nameN

For example, to import the fib function of module fibo, use the following statement:


>>> from fibo import fib, fib2
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

This declaration will not import the entire fibo module into the current namespace, it will only introduce the fib function in fibo.

from … import * statement

It is also possible to import the entire contents of a module into the current namespace using the following declaration:

from module_name import *

This provides an easy way to import all projects in a module. However, this statement should not be overused.

>>> from fibo import *
>>> fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377

Note : This will import all names except those starting with a single underscore (_). In most cases, Python programmers do not use this method, because the introduction of names from other sources is likely to overwrite existing definitions.

Dive into modules

In addition to method definitions, modules can also include executable code. These codes are generally used to initialize this module. This code will only be executed the first time it is imported.

Each module has its own independent symbol table, which is used as a global symbol table for all functions within the module.

Therefore, the module author can safely use these global variables inside the module without worrying about confusing other users' global variables.

On the other hand, when you really know what you are doing, you can also access functions within a module through notation such as module_name.itemname .

Modules can import other modules. Use import at the beginning of a module (or script, or elsewhere) to import a module. Of course, this is just a convention, not a requirement. The name of the imported module will be placed in the symbol table of the currently operating module.

__name__ attribute

The first time a module is introduced by another program, its main program will run. If we want a certain program block in the module not to be executed when the module is imported, we can use the __name__ attribute to make the program block only execute when the module itself is run.

#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')

The running output is as follows:

C:\Users\Lenovo\Desktop>python using_name.py
program itself is running

C:\Users\Lenovo\Desktop>python
Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import using_name
我来自另一模块
>>>

Description :

  • Each module has a _ name__ attribute. When its value is '_ main ', it indicates that the module itself is running, otherwise it is imported.
  • There are double underscores under _ name _ and _ main _, and _ _ removes the space in the middle like this.

dir() function

The configured function dir() can find all names defined within the module. Returned as a list of strings:

>>> import fibo, sys
>>> dir(fibo)
['__name__', 'fib', 'fib2']
>>> dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', 'version', 'version_info', 'warnoptions']

If no arguments are given, the dir() function lists all currently defined names:

C:\Users\Lenovo>cd Desktop

C:\Users\Lenovo\Desktop>python
Python 3.11.4 (tags/v3.11.4:d2340ef, Jun  7 2023, 05:45:37) [MSC v.1934 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__']
>>> a=[1,2,3,4,5]
>>> import fibo
>>> fib=fibo.fib
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'fib', 'fibo']
>>> a = 5 # 建立一个新的变量 'a'
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'fib', 'fibo']
>>>
>>> del a # 删除变量名a
>>> dir()
['__annotations__', '__builtins__', '__doc__', '__loader__', '__name__', '__package__', '__spec__', 'fib', 'fibo']
>>>

Standard module

Python itself comes with some standard module libraries, which will be introduced in the Python library reference document (that is, the "Library Reference Document" later).

Some modules are built directly into the parser. Although these are not built-in functions of some languages, they can be used very efficiently, even for system-level calls.

These components will be configured in different forms according to different operating systems. For example, the winreg module will only be provided for Windows systems.

It should be noted that there is a special module sys, which is built into every Python parser. The variables sys.ps1 and sys.ps2 define the strings corresponding to the primary prompt and secondary prompt:

>>> import sys
>>> sys.ps1
'>>> '
>>> sys.ps2
'... '
>>> sys.ps1 = 'C> '
C> print('Tarzan!')
Runoob!
C> 

Bag

Packages are a form of managing the Python module namespace, using "dot module names".

For example, if the name of a module is AB, then it represents a submodule B in package A.

Just like when using modules, you don't have to worry about the mutual influence of global variables between different modules. Using the dot module name format, you don't have to worry about the duplication of module names between different libraries.

In this way, different authors can provide NumPy modules or Python graphics libraries.

Let's say you want to design a set of modules (or call it a "package") that handle sound files and data in a unified manner.

There are many different audio file formats (basically distinguished by suffix names, such as: .wav, :file:.aiff, :file:.au,), so you need to have an ever-increasing set of modules for Convert between different formats.

And there are many different operations for this audio data (such as mixing, adding echo, adding equalizer functions, creating artificial stereo effects), so you also need an endless set of modules to handle these operations.

Here is a possible package structure (in a hierarchical file system):

sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...

When importing a package, Python will look for the subdirectories contained in the package based on the directories in sys.path.

A directory will only be recognized as a package if it contains a file called _ init _.py. This is mainly to prevent some clichéd names (such as string) from accidentally affecting the valid modules in the search path.

In the simplest case, just put an empty :file:_ init _.py. Of course, this file can also contain some initialization code or assign values ​​to the __all__ variable (to be introduced later).

Users can only import specific modules in one package at a time, such as:

import sound.effects.echo

This will import the submodule: sound.effects.echo. He must use his full name to access:

sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

Another way to import submodules is:

from sound.effects import echo

This also imports the submodule: echo, and it doesn't need those lengthy prefixes, so it can be used like this:

echo.echofilter(input, output, delay=0.7, atten=4)

Another variation is to directly import a function or variable:

from sound.effects.echo import echofilter

Likewise, this method will import the submodule: echo, and its echofilter() function can be used directly:

echofilter(input, output, delay=0.7, atten=4)

Note that when using from package import item , the corresponding item can be a submodule (subpackage) in the package, or other names defined in the package, such as functions, classes or variables.

The import syntax will first treat item as the name of a package definition. If it is not found, it will then try to import it as a module. If it is not found, an :exc:ImportError exception is thrown.

On the contrary, if you use the import form such as import item.subitem.subsubitem , except for the last item, all must be packages. The last item can be a module or a package, but it cannot be the name of a class, function or variable. .

Import from a package*

What happens if we use from sound.effects import * ?

Python will go into the file system, find all the submodules in the package, and import them one by one.

But this method does not work very well on the Windows platform, because Windows is a case-insensitive system.

On the Windows platform, we cannot determine whether a file called ECHO.py imported as a module is echo or Echo , or ECHO .

To solve this problem, we only need to provide an exact package index.

The import statement follows the following rules: If the package definition file _ init _.py has a list variable called _ all _ , then when using **from package import ***, all names in this list will be imported as package content. .

As the author of the package, don't forget to ensure that _all_ is also updated after updating the package .

The following example contains the following code in file:sounds/effects/_ init _.py :

__all__ = ["echo", "surround", "reverse"]

This means that when you use from sound.effects import *, you will only import these three submodules in the package.

If _ all _ is really not defined, then when using the syntax * from sound.effects import , no submodules in the package sound.effects will be imported . It just imports the package sound.effects and everything defined in it (possibly running the initialization code defined in _ init _.py ).

This will import all the names defined in _ init _.py . And it won't destroy all the explicitly specified modules we imported before this sentence. Take a look at this part of the code:

import sound.effects.echo
import sound.effects.surround
from sound.effects import *

In this example, before executing from...import , the echo and surround modules in the package sound.effects are imported into the current namespace. (Of course, it would be no problem if _ all _ was defined )

Generally we do not advocate using * this method to import modules, because this method often results in reduced code readability. However, this does save a lot of keystrokes, and some modules are designed to be imported only through specific methods.

Remember, you can never go wrong using from Package import specific_submodule . In fact, this is the recommended approach. Unless the submodule you want to import may have the same name as a submodule of another package.

If the package is a subpackage in the structure (such as the sound package in this example ), and you want to import a sibling package (a package of the same level), you have to use the import absolute path to import. For example, if the module sound.filters.vocoder wants to use the module echo in the package sound.effects , you would write from sound.effects import echo .

from . import echo
from .. import formats
from ..filters import equalizer

Relative imports, whether implicit or explicit, start from the current module. The name of the main module is always "_ main _". The main module of a Python application should always be referenced using an absolute path.

The package also provides an additional attribute __path__. This is a directory list. Each directory included in it has an __init__.py that serves this package. You must define it before other __init__.py is executed. This variable can be modified to affect modules and subpackages contained in the package.

This function is not commonly used and is generally used to expand the modules in the package.

Guess you like

Origin blog.csdn.net/weixin_40986713/article/details/132858034