简体   繁体   中英

Using "python -m" to call Python script not working

Basically the title. File structure below with code examples.

Relevant project structure:

drf/
├─ backend/
├─ py_client/
│  ├─ basic.py
├─ venv/
├─ requirements.txt

I know that using "python -m" is best practice for venvs, and I understand that the reason for this is to use the currently activated Python version, managing dependencies etc. etc.

But what I don't understand is why it affects running a script via CLI the way it does.

Method + Response 1:

(venv) PS C:\Users\cjrow\DjangoProjects\drf> python -m py_client/basic.py
C:\Users\cjrow\DjangoProjects\drf\venv\Scripts\python.exe: Error while finding module specification for 'py_client/basic.py' (ModuleNotFoundError: No module named 'py_client/basic'). Try using 'py_client/basic' instead of 'py_client/basic.py' as the module name.

So I followed the suggestion and removed the .py , though I don't even understand why that was a suggestion.

Method + Result 2:

(venv) PS C:\Users\cjrow\DjangoProjects\drf> python -m py_client/basic
C:\Users\cjrow\DjangoProjects\drf\venv\Scripts\python.exe: No module named py_client/basic

This obviously didn't work at all. So I tried without -m :

Method + Result 3

( basic.py just contains print("It's working") :

(venv) PS C:\Users\cjrow\DjangoProjects\drf> python py_client/basic.py
It's working

And then, just out of curiosity:

Method + Result 4:

(venv) PS C:\Users\cjrow\DjangoProjects\drf> python py_client/basic   
C:\Users\cjrow\AppData\Local\Programs\Python\Python311\python.exe: can't open file 'C:\\Users\\cjrow\\DjangoProjects\\drf\\py_client\\basic': [Errno 2] No such file or directory

I understand why 3 works and I understand why 4 doesn't work, but I don't understand why neither 1 nor 2 work.

Thanks!

When you use -m flag you are telling python to read the script as a module, this requires a special file in the folder where your script is with the name __init__.py more info here Why init .py . Then you can use -m flag. I reproduced you error with the following structure.

b/
|--a/
|--|script.py

Solved adding.

b/
|--a/
|--|script.py
|--|__init__.py

file script.py contains

print('hi')

b contains a and a contains script.py and init .py so from terminal I can do python3 -m bascript

hi

if I am in folder where b is or if you are in b itself then python3 -m a.script

hi

Or in a itself python3 -m script

hi

Hope this helps, this is my first answer.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM