introductory
What is the difference between modules, libraries and packages in python?
module: a .py file is a module.
lib: abstract concept, not in the same category as the other two, anything is a lib if you like, even if it's just a hello world.
package: a folder with __init__.py in it, don't really care what's in it, but in general it will contain some packages/modules.
How you have the following queries then this post is perfect for you!
- Sub-Question: Why is it normal to run unit tests in pycharm? But still, if I run it in the terminal, I get a package guide error?
- Subquestion: Pycharm runs fine, but the terminal gives an error:
ModuleNotFoundError: No module named
- Subquestion: Why does python run in vscode at a different path than pycharm?
- Sub-question: VSCode can't find relative path file
What is the current path?
Is the current path the path where the command was typed or the path where thepy
Path where the script file is located?
Interjections:Linux
etc. The command to view the current path ispwd
The current path in python is ()
❓ Question 1👉🏻:python
The current path of the program is to execute thepython
Paths such as scripts orpython
The path the script says it's on?
That is, when the following command is executed, the so-called current path istesting
The path to the folder is still The path where the file is located.
python testing/
✅ Answer: the current path is the path to enter the run command, not thepy
The path where the file is located.
For the command below 👇, it doesn't matter to distinguish between the two paths, but the path above 👆 is different
python
Relationship between the guide package path and the current path?
How does knowing this knowledge help in writing programs to avoid pitfalls? , take a look down the page!
❓ Question two 👉🏻: How can I see the path to Python's package guide?
- Subquestion: what is the order of package introduction in python?
- Subquestion: What folders does python go to when importing packages to find packages?
- Subquestion: What paths does python look for packages when importing packages?
I'm in/Users/bot/Desktop/code/ideaboom
Create a new file namedtesting
folder in thetesting
folder and create a new of the document.
The contents of the document are as follows.
import os import sys print('Current working path: ', ()) print('The path to the package is: ') for p in : print(p)
beginning of/Users/bot/Desktop/code/ideaboom
Run the command at:python testing/
The program output is as follows:
Current working path: /Users/bot/Desktop/code/ideaboom
The path to the package is.
/Users/bot/Desktop/code/ideaboom/testing
/Library/Frameworks//Versions/3.9/lib/
/Library/Frameworks//Versions/3.9/lib/python3.9
/Library/Frameworks//Versions/3.9/lib/python3.9/lib-dynload
/Users/bot/.local/share/virtualenvs/ideaboom-8ZWsq-JB/lib/python3.9/site-packages
- Phenomenon 1 👀: we can see that there are many guide paths.
The return is a list object, the search package, will start from the first element of the list early, such as
import django
I'll go first./Users/bot/Desktop/code/ideaboom/testing
Check to see if there is anything calleddjango
The package orDocumentation. Then go to the
/Library/Frameworks//Versions/3.9/lib/
etc. in order to find it.
A package in python is a package that contains__init__.py
Folders for documents
- Phenomenon 2 👀: you can see that the current path is executing the
python testing/
command, but instead of using the path to execute the command, the package path is the path to theThe path where the file is located.
- Phenomenon 3 👀: The first in line is the
The path where the file is located. The system paths are all slightly backward.
What's wrong with the primary package guide path not being the current path?
This is a typical problem, we tend to create a testing folder under the root directory of the project and put the files that need to be unit test related.
But when we enter the commandpython testing/
The time when theModuleNotFoundError: No module named xxx
The reason for this is the above mentioned: the primary package path is not the current path.
Originally, the xxx and testing folders were in the root directory of the project, and the path to the first package in the xxx folder was in the root directory of the project.python testing/
In the case that the primary guide path becomes thetesting
instead of the project root directory anymore! This is still hit the nail on the head
import xxx
Of course you can't find it.
How do you solve a problem when you know it?
Solve what 😨? Of course it's runningtetsing
folder below the Documentation errors
ModuleNotFoundError: No module named xxx
The question. 🤯
❓ Question 3: How do I change the path to the primary package guide for a Python program?
The primary python package path is The first element in the list, i.e. the path to the folder where the py file being run is located
Option 1: Dynamic modification
The most common way to do this is:
Add the current path to the and to avoid naming conflicts, it is better to add it to the head of the list rather than using the
append
Add to the tail. As for the original (undesired) primary guide package paths/Users/bot/Desktop/code/ideaboom/testing
It can be deleted or retained.
import os import sys print('Current working path: ', ()) print('The path to the package is: ') (0,()) # Add the current path to the for p in : print(p)
Program output: 👇
Current working path: /Users/bot/Desktop/code/ideaboom
The path to the package is.
/Users/bot/Desktop/code/ideaboom
/Users/bot/Desktop/code/ideaboom/testing
/Library/Frameworks//Versions/3.9/lib/
/Library/Frameworks//Versions/3.9/lib/python3.9
/Library/Frameworks//Versions/3.9/lib/python3.9/lib-dynload
/Users/bot/.local/share/virtualenvs/ideaboom-8ZWsq-JB/lib/python3.9/site-packages
But this solution is not very good, there are some drawbacks, such as the following code, it looks very inelegant, because according to python's code specification, the code related to package guide should be written at the top, this kind ofGuide package + code + guide package
The way in which the destruction of thepythonic
import os import sys import time import schedule from pathlib import Path import os import sys import time import schedule from pathlib import Path BASE_DIR = Path(__file__).resolve(). (0, str(BASE_DIR)) import django ()
Option 2: Use the environment variable PYTHONPATH
🥳 A better program 👇
Since the setting of the primary package path is the default execution of the python interpreter, can we specify the primary package path we need before the python interpreter starts?
By looking at the python --help command, we get to the following:👇
usage: /opt/homebrew/Cellar/[email protected]/3.8.12/bin/python3 [option] ... [-c cmd | -m mod | file | -] [arg] ... Options and arguments (and corresponding environment variables): -b : issue warnings about str(bytes_instance), str(bytearray_instance) and comparing bytes/bytearray with str. (-bb: issue errors) -B : don't write .pyc files on import; also PYTHONDONTWRITEBYTECODE=x -c cmd : program passed in as string (terminates option list) -d : debug output from parser; also PYTHONDEBUG=x -E : ignore PYTHON* environment variables (such as PYTHONPATH) -h : print this help message and exit (also --help) -i : inspect interactively after running script; forces a prompt even if stdin does not appear to be a terminal; also PYTHONINSPECT=x -I : isolate Python from the user's environment (implies -E and -s) -m mod : run library module as a script (terminates option list) -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 extension -q : don't print version and copyright messages on interactive startup -s : don't add user site directory to ; also PYTHONNOUSERSITE -S : don't imply 'import site' on initialization -u : force the stdout and stderr streams to be unbuffered; this option has no effect on stdin; also PYTHONUNBUFFERED=x -v : verbose (trace import statements); also PYTHONVERBOSE=x can be supplied multiple times to increase verbosity -V : print the Python version number and exit (also --version) when given twice, print more information about the build -W arg : warning control; arg is action:message:category:module:lineno also PYTHONWARNINGS=arg -x : skip first line of source, allowing use of non-Unix forms of #!cmd -X opt : set implementation-specific option. The following options are available: -X faulthandler: enable faulthandler -X showrefcount: output the total reference count and number of used memory blocks when the program finishes or after each statement in the interactive interpreter. This only works on debug builds -X tracemalloc: start tracing Python memory allocations using the tracemalloc module. By default, only the most recent frame is stored in a traceback of a trace. Use -X tracemalloc=NFRAME to start tracing with a traceback limit of NFRAME frames -X showalloccount: output the total count of allocated objects for each type when the program finishes. This only works when Python was built with COUNT_ALLOCS defined -X importtime: show how long each import takes. It shows module name, cumulative time (including nested imports) and self time (excluding nested imports). Note that its output may be broken in multi-threaded application. Typical usage is python3 -X importtime -c 'import asyncio' -X dev: enable CPython's "development mode", introducing additional runtime checks which are too expensive to be enabled by default. Effect of the developer mode: * Add default warning filter, as -W default * Install debug hooks on memory allocators: see the PyMem_SetupDebugHooks() C function * Enable the faulthandler module to dump the Python traceback on a crash * Enable asyncio debug mode * Set the dev_mode attribute of to True * destructor logs close() exceptions -X utf8: enable UTF-8 mode for operating system interfaces, overriding the default locale-aware mode. -X utf8=0 explicitly disables UTF-8 mode (even when it would otherwise activate automatically) -X pycache_prefix=PATH: enable writing .pyc files to a parallel tree rooted at the given directory instead of to the code tree --check-hash-based-pycs always|default|never: control how Python invalidates hash-based .pyc files file : program read from script file - : program read from stdin (default; interactive mode if a tty) arg ...: arguments passed to program in [1:] Other environment variables: PYTHONSTARTUP: file executed on interactive startup (no default) PYTHONPATH : ':'-separated list of directories prefixed to the default module search path. The result is . PYTHONHOME : alternate <prefix> directory (or <prefix>:<exec_prefix>). The default module search path uses <prefix>/lib/. PYTHONCASEOK : ignore case in 'import' statements (Windows). PYTHONUTF8: if set to 1, enable the UTF-8 mode. PYTHONIOENCODING: Encoding[:errors] used for stdin/stdout/stderr. PYTHONFAULTHANDLER: dump the Python traceback on fatal errors. PYTHONHASHSEED: if this variable is set to 'random', a random value is used to seed the hashes of str and bytes objects. It can also be set to an integer in the range [0,4294967295] to get hash values with a predictable seed. PYTHONMALLOC: set the Python memory allocators and/or install debug hooks on Python memory allocators. Use PYTHONMALLOC=debug to install debug hooks. PYTHONCOERCECLOCALE: if this variable is set to 0, it disables the locale coercion behavior. Use PYTHONCOERCECLOCALE=warn to request display of locale coercion and locale compatibility warnings on stderr. PYTHONBREAKPOINT: if this variable is set to 0, it disables the default debugger. It can be set to the callable of your debugger of choice. PYTHONDEVMODE: enable the development mode. PYTHONPYCACHEPREFIX: root directory for bytecode cache (pyc) files.
After looking around, I feel that thisPYTHONHOME
It's a savior, but it's not really oh, it's exactly that unassumingPYTHONPATH
testing/
import os import sys print('Current working path: ', ()) print('The path to the package is: ') for p in : print(p)
We can start the program using the following: 👇
PYTHONPATH=$(pwd) python testing/
At this point the output of the program becomes: 👇
(ideaboom) ╭─bot@ ~/Desktop/code/ideaboom ‹master*›
╰─➤ PYTHONPATH=$(pwd) python testing/
Current working path: /Users/bot/Desktop/code/ideaboom
The path to the package is.
/Users/bot/Desktop/code/ideaboom/testing
/Users/bot/Desktop/code/ideaboom
/Library/Frameworks//Versions/3.9/lib/
/Library/Frameworks//Versions/3.9/lib/python3.9
/Library/Frameworks//Versions/3.9/lib/python3.9/lib-dynload
/Users/bot/.local/share/virtualenvs/ideaboom-8ZWsq-JB/lib/python3.9/site-packages
Let's go over it again.PYTHONPATH=$(pwd) python testing/
, which is equivalent toPYTHONPATH=/Users/bot/Desktop/code/ideaboom python testing/
.
existpython testing/
increasePYTHONPATH=$(pwd)
environment variables are limited to the current command run and do not propagate to the current shell environment.
The above is a comprehensive analysis of python current path and guide package path problem in detail, more information about python current path guide package path please pay attention to my other related articles!