Module 1
Modules can be regarded as a collection of functions.
A stack of functions can be placed inside a py file, so a py file can be regarded as a module.
If the file name of this py file is {module Py, and the module name is "module".
1. Four forms of modules
In Python, there are four types of modules:
Custom module: if you write a py file and write a bunch of functions in the file, it is called a custom module, which is written in python Py file
Third party modules: C or C + + extensions that have been compiled as shared libraries or DLL s, such as requests
Built in module: a built-in module written in C and linked to the python interpreter, such as time
Package (folder): a folder that organizes a series of modules together (Note: there is a _init_.py file under the folder, which is called package)
2. Why use modules?
Using third-party or built-in modules is a kind of doctrine, which can greatly improve the development efficiency.
The custom module writes the public functions used in our own program into a python file, and then the components of the program can reference the functions of the custom module by importing.
2, How to use modules
Generally, we use import and from import... Import module.
With the following spam Py as an example.
# spam.py print('from the spam.py') money = 1000 def read1(): print('spam module:', money) def read2(): print('spam module ') read1() def change(): global money money = 0
1. import module name
The syntax is as follows:
import module1[, module2[,... moduleN]
import the imported module, which needs to be prefixed for access.
import three things happened when the module was imported for the first time:
Create a module namespace based on the module
Execute the file corresponding to the module, and throw the names generated during execution into the module namespace
Get a module name in the current execution file
Note: the repeated import of a module will directly reference the previously created results, and the module files will not be executed repeatedly.
# run.py import spam # from the spam.py import spam money = 111111 spam.read1() # 'spam Module: 1000' spam.change() print(spam.money) # 0 print(money) # 111111
Import rename: the smt variable points to the namespace of the span module
# run.py import spam as sm money = 111111 sm.money sm.read1() # 'spam Module: 1000' sm.read2 sm.change() print(money) # 1000
Import multiple modules
import spam, time, os # The following methods are recommended to import spam import time import os
2. from module name import specific function
The syntax is as follows:
from modname import name1[, name2[, ... nameN]]
This declaration will not import the whole module into the current namespace, it will only introduce one or more functions in the module.
from...import... The imported module does not need to be prefixed for access.
from...import... Three things happened when the module was imported for the first time:
Create a module namespace based on the module
Execute the file corresponding to the module, and throw the names generated during execution into the module namespace
Get a name in the namespace of the current executable file. The name directly points to a name in the module, which means that it can be used directly without any prefix
Advantages: no prefix, more concise code
Disadvantages: it is easy to conflict with the name in the namespace in the current execution file
# run.py from spam import money
from spam import money,read1 money = 10 print(money) # 10
rom... Import * statement: import all functions in the file:
# spam.py __all__ = ['money', 'read1'] # Only 'money' and 'read1' are allowed to be imported
# run.py from spam import * # Import spam.py All functions within, but will be limited to__all__ money = 111111 read1() # 'spam Module: 1000' change() read1() # 'spam Module: 0' print(money) # 111111
3. Circular import
Circular import occurs when:
# m1.py print('from m1.py') from m2 import x y = 'm1' # m2.py print('from m2.py') from m1 import y x = 'm2'
You can use the function definition stage to only recognize the characteristics of syntax to solve the problem of circular import, or essentially solve the problem of circular import, but the best solution is not to have circular import.
Scheme I:
# m1.py print('from m1.py') def func1(): from m2 import x print(x) y = 'm1' # m2.py print('from m2.py') def func1(): from m1 import y print(y) x = 'm2'
Scheme II:
5,# m1.py print('from m1.py') y = 'm1' from m2 import x # m2.py print('from m2.py') x = 'm2' from m1 import y
4. dir() function
The built-in function dir() can find all the names defined in the module. Returns as a list of strings:
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 parameter is given, the dir() function lists all currently defined names:
a = [1, 2, 3, 4, 5] import fibo fib = fibo.fib print(dir()) # Get a list of attributes defined in the current module # ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys'] b = 5 # Create a new variable 'a' print(dir()) # ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a', 'b'] del b # Delete variable name a print(dir()) # ['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']
Three. Module search path
1. The order in which modules are found when importing modules
1. First look for the imported modules in memory
If we're running run Py file, quickly delete mmm Py file, we will find that the file will continue to run without error, because MMM has been imported into memory. If we run run again Py, because mmm Py has been deleted.
# test.py import m1 # from m1.py Imported from file,Then it will generate m1 Module namespace import time # delete m1.py file,m1 The module namespace still exists time.sleep(10) import m1 # If no error is reported, the m1 module must not be obtained from the file, but from memory
2. Built in module
Verify that you first find the built-in time, not the custom time Py file.
# time.py print('from time.py') # run.py import time print(time) #
3. Environment variable sys Path (emphasis: the first value of sys.path is the folder where the current executable file is located)
import sys for n in sys.path: print(n) # C:\PycharmProjects\untitled\venv\Scripts\python.exe C:/PycharmProjects/untitled/hello.py # C:\PycharmProjects\untitled # C:\PycharmProjects\untitled # C:\Python\Python38\python38.zip # C:\Python\Python38\DLLs # C:\Python\Python38\lib # C:\Python\Python38 # C:\PycharmProjects\untitled\venv # C:\PycharmProjects\untitled\venv\lib\site-packages
If mmm Py is in C:\PycharmProjects\untitled\day16 path, and the execution file path is C:\PycharmProjects\untitled. If ordinary import will certainly report an error, we can add C:\PycharmProjects\untitled\day16 to the environment variable sys Path to prevent error reporting.
# run.py import sys sys.path.append(r'C:\PycharmProjects\untitled\day16') print(sys.path) import mmm mmm.f1()
2. The search path is subject to the executable file
Suppose we have files with the following directory structure, and the codes in the files are:
And hello and spam Py is not in the same directory, so run The environment variable of Py cannot be found m2 directly, so it needs to be imported from the folder
from aa import spam print(spam.money)
4, Two uses of Python files
When a module is first introduced by another program, its main program will run. If we want a program block in the module not to execute when the module is introduced, we can use__ name__ Property to make the block execute only when the module itself is running.
python files have two purposes: one is to execute files; The other is imported as a module.
Each module has one__ name__ Property when its value is' '__ main__' It indicates that the module itself is running, otherwise it is introduced.
1. When run When py is running, AAA Py is treated as a reference module and its__ name__ == 'aaa '(module name), f1() in aaa.py will be executed.
# aaa.py x = 1 def f1(): print('from f1') f1() # run.py import aaa
2,aaa. When py is treated as an executable, add__ name__ == '__main__', Run AAA alone Py will execute AAA f1() in py. run. The PY runtime prevents f1() from executing.
# aaa.py x = 1 def f1(): print('from f1') if __name__ == '__main__': f1()
5, Package
Package is a form of managing Python module namespace. The essence of package is a package containing py file folder.
The package adopts "point module name". For example, if the name of a module is A.B, it represents sub module B in package a.
The directory contains only one file called__ init__.py file will be considered a package.
When importing a package, Python will import it according to sys Path to find the subdirectories contained in the package.
Three things happen when importing packages:
Create a package namespace
Because the package is a folder, the package cannot be executed, so execute the under the package py file, which stores the names generated during execution in the package namespace (that is, the names stored in the package namespace are all from. py)
Get a name aaa in the current execution file, which points to the package namespace
The import package is under the import package py, importing m1 is importing m1__ init__.
1. There are two ways to import:
import ... :
import item. subitem. In the import form of subitem, except the last item, it must be a package, and the last item can be a module or package, but it can not be the name of a class, function or variable.
from ... import...:
When using the form of from package import item, the corresponding item can be a sub module (sub package) in the package or other names defined in the package, such as functions, classes or variables.
2. import imports the modules in the package
Import can only import a specific module in a package at a time. It must use its full name to access it.
import aaa.bbb.m3 print(aaa.bbb.m3.func3())
Functions and variables cannot be imported in import mode: import AAA bbb. m3. F3 error
3. from import mode:
Import specific modules in the module
This approach does not require those verbose prefixes for access
from aaa.bbb import m3 print(m3.func3())
Import specific functions in the module
This approach does not require those verbose prefixes for access
from aaa.bbb.m3 import func3 print(func3())
4. Absolute import and relative Import
Absolute import:
# aaa/.py from aaa.m1 import func1 from aaa.m2 import func2
Relative Import:
. Represents the folder where the currently imported file is located
.. Represents the upper level of the folder where the currently imported file is located
... Represents the upper level of the folder where the currently imported file is located
from .m1 import func1 from .m2 import func2
5,from...import *
The import statement follows the following rule: if the package definition file init_ Py has a name called__ All list variable, then when using from package import *, all names in the list will be imported as package content.
Here is an example in file:sounds/effects/__init__.py contains the following code:
__all__ = ["echo", "surround", "reverse"]
This means that when you use from sound Effects import * when using this method, you will only import the three sub modules in the package.
6, Catalog specification for software development
In order to improve the readability and maintainability of the program, we should design a good directory structure for the software, which is as important as the standard coding style. In short, the software code is divided into file directories. Suppose you want to write an ATM software, you can manage your software code according to the following directory structure:
ATM/ |-- core/ | |-- src.py # Business core logic code | |-- api/ | |-- api.py # Interface file | |-- db/ | |-- db_handle.py # Operation data file | |-- db.txt # Store data files | |-- lib/ | |-- common.py # Sharing function | |-- conf/ | |-- settings.py # Configuration related | |-- bin/ | |-- run.py # The startup file of the program is generally placed in the root directory of the project, because the folder where the running file is located will be used as the default folder when running sys.path The first path, which eliminates the steps of dealing with environment variables | |-- log/ | |-- log.log # log file | |-- requirements.txt # External storage of software dependencies Python Package list, see https://pip.readthedocs.io/en/1.1/requirements.html |-- README # project description file
settings.py
# settings.py import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) DB_PATH = os.path.join(BASE_DIR, 'db', 'db.txt') LOG_PATH = os.path.join(BASE_DIR, 'log', 'user.log') # print(DB_PATH) # print(LOG_PATH)
common.py
# common.py import time from conf import settings def logger(msg): current_time = time.strftime('%Y-%m-%d %X') with open(settings.LOG_PATH, mode='a', encoding='utf-8') as f: f.write('%s %s' % (current_time, msg))
src.py
# src.py from conf import settings from lib import common def login(): print('land') def register(): print('register') name = input('username>>: ') pwd = input('password>>: ') with open(settings.DB_PATH, mode='a', encoding='utf-8') as f: f.write('%s:%s\n' % (name, pwd)) # Log...... common.logger('%s registration succeeded'% name) print('registration succeeded ') def shopping(): print('shopping') def pay(): print('payment ') def transfer(): print('transfer') func_ DIC = {'1': login, '2': register, '3': shopping, '4': pay, '5': transfer,} def run(): while true: Print ("" "1 login 2 registration 3 shopping 4 payment 5 transfer 6 exit" "") choice = input (> >: ') strip() if choice == '6': break if choice not in func_ DIC: Print ('input wrong command, silly fork ') continue func_dic[choice]()
run.py
# run.py import sys import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.append(BASE_DIR) from core import src if __name__ == '__main__': src.run()