1

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!

1
  • If you just want to run a script, "python myscript.py" When you install a module with a setup.py then the -m flag is more useful. Commented Nov 24, 2022 at 16:54

1 Answer 1

1

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 b.a.script

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.

Sign up to request clarification or add additional context in comments.

1 Comment

In what folder are you whe you call `python3 -m a-script? are you in b or in root?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.