Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
792 views
in Technique[技术] by (71.8m points)

python - Python3 submodules setup does not update paths when run with -m switch

I have the following project structure:

server/
   server.py
   __init__.py

   sockets/
      module.py
      __init__.py

I set PYTHONPATH to one directory above server (for example /home/user/server contains server, PYTHONPATH is set /home/user).

The main file is server.py; it imports modules:

import sockets
from sockets.module import Module

When I run python3 $PYTHONPATH/server/server.py directly it works perfectly. However when I call python3 -m server.server.py it fails, despite the fact that it is explicitly recommended to avoid Python path hell, but it fails to find the the module, with an ugly message:

/usr/bin/python3: Error while finding spec for 'server.server.py' (<class 'ImportError'>: No module named 'sockets')

Why does the module import fail to import submodules? How to properly setup sub-packages?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

The behaviour is entirely correct; sockets is not a top-level module. However, when you use $PYTHONPATH/server/server.py, Python also adds $PYTHONPATH/server/ to the Python search path, so now sockets is a top-level module. You should never directly run files in a package.

Import sockets relative to the current package:

from . import sockets
from .sockets.module import Module 

or use fully-qualified imports:

from server import sockets
from server.sockets.module import Module 

Also see the Interface Options section of the Python Setup and Usage section in the fine manual:

If the script name refers directly to a Python file, the directory containing that file is added to the start of sys.path, and the file is executed as the __main__ module.

Note that the -m switch takes a python identifier, not a filename, so use:

python -m server.server

leaving of the .py extension.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...