Importing function from program in a subdirectory - python

Using python I launch a script from a certain point. From here, there's the subdirectory "A" where it's contained the file "B.py", which contains a class called "C"
from A import C
Traceback
ImportError: cannot import name 'C' from 'A' (unknown location). Is there an easy way to make python look in A then in B and finally get C? Thank you

If I have a directory structure like the following:
A -----------|
|- B.py
test.py
B.py contains the following code:
class C:
def __init__(self):
print("I made it to C!")
If I'm writing test.py to need an instance of C I need to import like this:
from A.B import C
myInst = C()
And I get the following output when I run test.py
I made it to C!
Alternatively, you can add the path to the directory containing B.py to your PATH with the sys module. To show this, I have put the file E.py in the structure of A/B/C/D/E.py along with an empty file named __init__.py
'=
E.py contains the following code:
class F:
def __init__(self):
print("I made it to C!")
test.py contains the following code:
import sys
sys.path.insert(0, "./A/B/C/D/") # You can put the absolute path
from E import F
myInst = F()
And I get the output:
I made it to C!

Related

How to use variables in other .py files

I have file A.py in a package with a class and a list as class attribute or class variable. File A run a loop to update value to that list. How can I get the list and all changes to file B.py (in another package).
When using only 'class attributes', the values are static, a simple 'import' should work.
For example, proj/package1/A.py:
class A:
attr1 = "foo"
attr2 = "bar"
Create file __init__.py in all directories: current, package1, package2
Import A from proj dir in proj/B.py:
from package1.A import *
print(A.attr1)
print(A.attr2)
Import A from non-parent dir, eg. proj/package2/B.py
import sys
sys.path.append("package1") # Run programme in `proj` dir
from A import *
print(A.attr1)
print(A.attr2)

Why my __init__.py doesn't work in the module?

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?
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 : )
You have to import the variable:
from dir import project_root
Where dir is the directory you are in

Creating importable Python 3 package / module

I am having trouble creating an importable Python package/library/module or whatever the right nomenclature is. I am using Python 3.7
The file structure I am using is:
Python37//Lib//mypackage
mypackage
__init__.py
mypackage_.py
The code in __init__.py is:
from mypackage.mypackage_ import MyClass
The code in mypackage_.py is:
class MyClass:
def __init__(self, myarg = None):
self.myvar = myarg
And from my desktop I try running the following code:
import mypackage
x = MyClass(None)
But get the following error:
Traceback (most recent call last):
File "C:\Users\***\Desktop\importtest.py", line 3, in <module>
x = MyClass(None)
NameError: name 'MyClass' is not defined
You haven't imported the name MyClass into your current namespace. You've imported mypackage. To access anything within mypackage, you need to prefix the name with mypackage.<Name>
import mypackage
x = mypackage.MyClass(None)
As #rdas says, you need to prefix the name with mypackage.<Name>.
I don't recommend doing this, but you can wildcard import in order to make x = MyClass(None) work:
from mypackage import *
Now, everything from mypackage is imported and usable in the current namespace. However, you have to be careful with wildcard imports because they can create definition conflictions (if multiple modules have the same name for different things).

Import a whole folder of python files

I am making a bot in python 3 and wish it to be easily expanded so I have a central file and then one for each command. I wish to know if there is a way to import a sub-directory full of modules without importing each separately. For example:
example
├── commands
│   ├── bar.py
│   └── foo.py
└── main.py
And the code in main.pywould be something like:
import /commands/*
Thanks :D
Solution:
Import each separately with:
from commands import foo, bar
from commands import * Does not work.
If you're using python3, the importlib module can be used to dynamically import modules. On python2.x, there is the __import__ function but I'm not very familiar with the semantics. As a quick example,
I have 2 files in the current directory
# a.py
name = "a"
and
# b.py
name = "b"
In the same directory, I have this
import glob
import importlib
for f in glob.iglob("*.py"):
if f.endswith("load.py"):
continue
mod_name = f.split(".")[0]
print ("importing {}".format(mod_name))
mod = importlib.import_module(mod_name, "")
print ("Imported {}. Name is {}".format(mod, mod.name))
This will print
importing b Imported <module 'b' from '/tmp/x/b.py'>.
Name is b
importing a Imported <module 'a' from '/tmp/x/a.py'>.
Name is a
Import each separately with:
from commands import bar and
from commands import foo
from commands import * Does not work.

Issue with importing my classes

Consider that I have 3 files.
I am trying to put different import function in one file and call that file i.e., File2 in this case directly.
File1.py
class generalTools():
def waitAppear():
wait()
File 11.py
class machinedata():
def max():
maxtime()
File2.py
import File1
import File11
self.generalTools = File1.generalTools()
self.machinedata=machinedata.max()
File3.py
from File2 import *
Note here I am not creating an object; just trying to call File1->waitAppear()
self.generalTools.waitAppear(self)
Whenever I execute above code, it throws error saying "generaTool has no instance"
What's wrong with the above code?

Categories