1

I am trying to add 'project_root' into __init__.py and all modules can use it, but it doesn't work.

Environment: Python 3.7.0 MACOS MOJAVE

file structure

·
├── __init__.py
└── a.py

the codes in __init__.py file:

import sys

project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(project_root)

and in another file

print(project_root)

If I run python a.py in the same dir ,or run python a.py out of the dir, error are the same below:

Traceback (most recent call last):
  File "a.py", line 1, in <module>
    print(project_root)
NameError: name 'project_root' is not defined

My question is why it doesn't work and how to fix it. Another question is what if you want to share some variables for other modules in a same package, how to do it?

4
  • 3
    It's unclear why you expected that would work. Declaring a variable in __init__.py doesn't make it in scope for every other file in the directory. I'd recommend reading e.g. docs.python.org/3/tutorial/modules.html. Commented Oct 22, 2019 at 10:07
  • @jonrsharpe Thank you, I will take a look at the link first. I want that work because I don't want to define project_root in every file. Commented Oct 22, 2019 at 10:38
  • Why would you need to define project_root in every file? Commented Oct 22, 2019 at 10:39
  • @jonrsharpe because I have to operate csv files in another dir, so I need to use project_root path to generate csv file path. Commented Oct 22, 2019 at 10:42

2 Answers 2

1

Let us try to understand by example.

Code and directory explanation:

Suppose we have the following directory and file structure:

dir_1
    ├── __init__.py
    └── a.py
b.py

__init__.py contains:

import sys,os

# Just to make things clear
print("Print statement from init")

project_root = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
sys.path.append(project_root)

a.py contains:

def func():
    print("func from a.py")

Let us start importing things:

Suppose you start with having the following code in b.py:

from dir_1.a import func

func()

Executing the above will give the following output:

Print statement from init
func from a.py

So, from the above, we understand that the print statement from __init__.py is being executed. Now, let's add print(project_root) in b.py:

from dir_1.a import func

func()
print(project_root)

Executing the above will result in an error saying:

...
NameError: name 'project_root' is not defined

This happened because we did not have to import the print statement from __init__.py it just gets executed. But that is not the case for a variable.

Let's try to import the variable and see what happens:

from dir_1.a import func
from dir_1 import project_root

func()
print(project_root)

Executing the above file will give the following output:

Print statement from init
func from a.py
/home/user/some/directory/name/dir_1

Long story short, you need to import the variable defined in __init__.py or anywhere else in order to use it.

Hope this helps : )

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

1 Comment

Thanks @Amit Yadav, I understand your example.So if I want to use the project_root argument inside the package (files in dir), __init__.py doesn't work because it won't be execute while I execute file in the dir.
0

You have to import the variable:

from dir import project_root

Where dir is the directory you are in

1 Comment

I tried, suppose the dir is tmp, I got the error ``` Traceback (most recent call last): File "a.py", line 1, in <module> from tmp import project_root ModuleNotFoundError: No module named 'tmp' ```

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.