Importing * in Python 3.7 Using __init__.py File - python

First of all here is my directory structure:
Root
- models
car.py
__init__.py
hello.py
Inside __init__.py I have the following:
__all__ = ["car"]
Inside hello.py I try to import everything from models folder:
from models import *
car = Car()
This gives me the error:
Traceback (most recent call last):
File "hello.py", line 4, in <module>
car = Car()
NameError: name 'Car' is not defined
What am I doing wrong?

You will have to specify what class you would like to import into the attribute __all__ of your __init__.py file. See below the example:
from car import *
__all__ = ["Car"]

If you want to have the class Car directly accessible in hello.py after you do from models import *, in the __init__.py file, put from models.car import Car.
__all__, on the other hand, typically lists names of modules, like what you have above. You could change hello.py to be as follows and your current __init__.py that consists of __all__ = ["car"] will work:
from models import *
car_obj = car.Car() # Reference module.class instead of just the class

From the python docs:
if a package’s __init__.py code defines a list named __all__, it is taken to be the list of module names that should be imported when from package import * is encountered.
This means that your hello.py has just imported the car module into it's namespace, not the Car class. Therefore this would work.
from models import *
auto = car.Car()

You missed one step there.
Try:
from models import *
car = car.Car()
Or try:
from models.car import *
car = Car()

__all__ just controls what will be exported by using * in current scope.
In your case, Car is not in your __init__.py's scope. So it is meaningless.
To solve this problem, you need to import Car into __init__.py's scope, that's all.
I understand that you think just by using __all__, you can directly access the class in car.py, but that's not true. __all__ does nothing else but control exports in current scope.

Related

import error when importing module from the same directory [duplicate]

I have a directory that stores all the .py files.
bin/
main.py
user.py # where class User resides
dir.py # where class Dir resides
I want to use classes from user.py and dir.py in main.py.
How can I import these Python classes into main.py?
Furthermore, how can I import class User if user.py is in a sub directory?
bin/
dir.py
main.py
usr/
user.py
Python 2
Make an empty file called __init__.py in the same directory as the files. That will signify to Python that it's "ok to import from this directory".
Then just do...
from user import User
from dir import Dir
The same holds true if the files are in a subdirectory - put an __init__.py in the subdirectory as well, and then use regular import statements, with dot notation. For each level of directory, you need to add to the import path.
bin/
main.py
classes/
user.py
dir.py
So if the directory was named "classes", then you'd do this:
from classes.user import User
from classes.dir import Dir
Python 3
Same as previous, but prefix the module name with a . if not using a subdirectory:
from .user import User
from .dir import Dir
I just learned (thanks to martineau's comment) that, in order to import classes from files within the same directory, you would now write in Python 3:
from .user import User
from .dir import Dir
From python3.3 upwards, __init__.py is no longer necessary. If the current directory of the console is the directory where the python script is located, everything works fine with
import user
However, this won't work if called from a different directory, which does not contain user.py.
In that case, use
from . import user
This works even if you want to import the whole file instead of just a class from there.
In your main.py:
from user import Class
where Class is the name of the class you want to import.
If you want to call a method of Class, you can call it using:
Class.method
Note that there should be an empty __init__.py file in the same directory.
If user.py and dir.py are not including classes then
from .user import User
from .dir import Dir
is not working. You should then import as
from . import user
from . import dir
You can import the module and have access through its name if you don't want to mix functions and classes with yours
import util # imports util.py
util.clean()
util.setup(4)
or you can import the functions and classes to your code
from util import clean, setup
clean()
setup(4)
you can use wildchar * to import everything in that module to your code
from util import *
clean()
setup(4)
To make it more simple to understand:
Step 1: lets go to one directory, where all will be included
$ cd /var/tmp
Step 2: now lets make a class1.py file which has a class name Class1 with some code
$ cat > class1.py <<\EOF
class Class1:
OKBLUE = '\033[94m'
ENDC = '\033[0m'
OK = OKBLUE + "[Class1 OK]: " + ENDC
EOF
Step 3: now lets make a class2.py file which has a class name Class2 with some code
$ cat > class2.py <<\EOF
class Class2:
OKBLUE = '\033[94m'
ENDC = '\033[0m'
OK = OKBLUE + "[Class2 OK]: " + ENDC
EOF
Step 4: now lets make one main.py which will be execute once to use Class1 and Class2 from 2 different files
$ cat > main.py <<\EOF
"""this is how we are actually calling class1.py and from that file loading Class1"""
from class1 import Class1
"""this is how we are actually calling class2.py and from that file loading Class2"""
from class2 import Class2
print Class1.OK
print Class2.OK
EOF
Step 5: Run the program
$ python main.py
The output would be
[Class1 OK]:
[Class2 OK]:
Python 3
Same directory.
import file:log.py
import class: SampleApp().
import log
if __name__ == "__main__":
app = log.SampleApp()
app.mainloop()
or
directory is basic.
import in file: log.py.
import class: SampleApp().
from basic import log
if __name__ == "__main__":
app = log.SampleApp()
app.mainloop()
from user import User
from dir import Dir
For Python 3+, suppose you have this structure:
A/
__init__.py
bar.py
foo.py
In your __init__.py file, you can put from . import foo
then you can import foo in bar file
# A/bar.py
from foo import YourClass
The purpose of the __init__.py files is to include optional initialization code that runs as different levels of a package are encountered. everything you put in the __init__.py will be initialized during the package load.
I'm not sure why this work but using Pycharm build from file_in_same_dir import class_name
The IDE complained about it but it seems it still worked. I'm using Python 3.7
For python3
import from sibling: from .user import User
import from nephew: from .usr.user import User
If you have filename.py in the same folder, you can easily import it like this:
import filename
I am using python3.7
Python3
use
from .user import User inside dir.py file
and
use from class.dir import Dir inside main.py
or from class.usr import User inside main.py
like so
# My Python version: 3.7
# IDE: Pycharm 2021.1.2 Community
# Have "myLib" in folder "labs":
class Points:
def __init__(self, x = 0, y = 0):
self.__x = x
self.__y = y
def __str__(self):
return f"x = {self.__x}, y = {self.__y}"
# Have "myFile" in (same) folder "labs":
from myFile import Point
p1 = Point(1, 4)
p2 = Point(1, 4)
print(f"p1: {p1}, p2: {p2}")
# Result:
# p1: x = 1, y = 4, p2: x = 1, y = 4
# Good Luck!
Indeed Python does not provide an elegant solution for this everyday use-case. It is especially problematic when you are testing your code that eventually will be delivered as part of a Python package. Here is an approach that has worked for me:
dir
|
file1.py
file2.py
And let's say you want to import file2 from file1.
# In file1.py:
try:
# This works when packaged as Python package
from . import file2
except:
# This works when simply invoking file1 as a module (i.e. python file1)
import file2
# rest of the code ...
I cannot submit an edit for the top answer, so based on some pointers given in comments above, another thing to try out is:
from subfolder.MyClassFile import MyClass
And that's it. Just remember to have an __init__.py empty file in our subfolder.
Just for reference, the solution works if your structure is something like this:
your_project/
__ini__.py
main.py
subfolder/
__init__.py
MyClassFile.py <-- You want this
MyClassFile.py contains the class MyClass.
Just too brief,
Create a file __init__.py is classes directory and then import it to your script like following (Import all case)
from classes.myscript import *
Import selected classes only
from classes.myscript import User
from classes.myscript import Dir
to import from the same directory
from . import the_file_you_want_to_import
to import from sub directory the directory should contain
init.py
file other than you files then
from directory import your_file

How to solve this circular import problem?

I have a library like this. wckg is the library name
wckg:
__init__.py
api/wckg_api.py
In __init__.py, I import the wckg_api scope and have an enum defined:
from wckg.api import wckg_api
class RelType(Enum):
a = 1
b = 2
WCKG = wckg_api.Wckg()
In api/wckg_api.py:
from wckg import RelType
class Wckg(object):
pass
As you can see, from wckg_api.py, it imports RelType from __init__, and at the same time it imports wckg_api from from wckg.api.py to create the Wckg object. This is circular and it reports an error:
ImportError: cannot import name 'RelType' from 'wckg' (/Users/comin/nlpc/wckg/wckg/init.py)
Is there a way to resolve this issue? init defined the interfaces and wckg_api.py is supposed to define the implementations of interfaces. I dont' want to define the constant RelType in wckg_api.py because I don't want users to import those constant types when users call a function from init. Those types can be immediately available to users. But since init also need to import something from wckg_api.py, it creates this circular import issue.
Is this a typical issue?
I would fix this like that:
wckg:
__init__.py
api/wckg_api.py
api/_rel_type.py
api/wckg_api.py:
from ._rel_type import RelType
class Wckg(object):
pass
api/_rel_type.py:
class RelType(Enum):
a = 1
b = 2
and under __init__.py:
from wckg.api import wckg_api, RelType
WCKG = wckg_api.Wckg()

import on Python doesn't work as expected

Although the variable should be imported, I get "name X is not defined" exception.
main.py
from config import *
from utils import *
say_hello()
utils.py
from config import *
def say_hello():
print(config_var)
config.py
from utils import *
config_var = "Hello"
Trying to run "main.py":
Traceback (most recent call last):
File "main.py", line 3, in
say_hello()
File "C:\Users\utils.py", line 3, in say_hello
print(config_var)
NameError: name 'config_var' is not defined
What happened here? Why some_var is not accessible from utils.py?
You are importing config in util and util in config which will causing this error(create cross loop). remove from utils import * from config.py and then try this.
And in main.py you don't need to import the from config import * unless you are using variables from config directly in your main()
you should also import config.config_var, since this variable belongs to that specific module
You are creating to many import statements perhaps try the following below, but also you need to define a parameter in utils.py if you are passing a parameter through there.
In utils.py we require a parameter to be passed since you want to print out the appropriate value, In config.py you are defining a value. Then in main.py as discussed before using the wildcard operator "*" isn't entirely good in this situation then in order to call the respective functions you need to address them through their file name
In utils.py :
def say_hello(config_var):
print(config_var)
In config.py
config_var = "Hello"
Then in main.py
import config as cn
import utils as ut
ut.say_hello(cn.config_var)
Check out this thread for how to write python modules as well How to write a Python module/package?

how to import a python class's moudle?

I have this main.py, in it:
import uuid
class tools(object):
def generate_uuid(self):
return self.uuid.uuid4()
in my calling program callmain.py, I have
import main
result = main.tool.generate_uuid()
print ("result")
if I run my callmain.py: I get
"TypeError: generate_uuid() missing 1 required positional argument:
'self'
if I add self to the line
result = main.tool.generate_uuid(self): I get
NameError: name 'self' is not defined
How to fix this? thank for help.
because you should make a object from your class first. then call your sub function like this:
import main
result = tools()
result.generate_uuid()
print(result) # "result" is a string! you should just call result without any "".
If you want to use the module of a class you have to create an instance of that class first and call if from that instance, that way the self argument is passed a valid reference to an instance of that class. For example:
import main
tools_instance = main.tools()
result = tools_instance.generate_uuid()
The style of importing shown in your question looks like a package. In packages a folder of python files __init__.py can be arranged in a particular way, documented here Python Packages. An example from the docs
parent/
__init__.py
one/
__init__.py
two/
__init__.py
three/
__init__.py
So an package of the format
main/
__init__.py
tools/
__init__.py # Add function 'generate_uuid' in this file
Could be utilized as follow:
import main
result = main.tools.generate_uuid()
print(result)

Import classes from child directory python

I've been trying to import some python classes which are defined in a child directory. The directory structure is as follows:
workspace/
__init__.py
main.py
checker/
__init__.py
baseChecker.py
gChecker.py
The baseChecker.py looks similar to:
import urllib
class BaseChecker(object):
# SOME METHODS HERE
The gChecker.py file:
import baseChecker # should import baseChecker.py
class GChecker(BaseChecker): # gives a TypeError: Error when calling the metaclass bases
# SOME METHODS WHICH USE URLLIB
And finally the main.py file:
import ?????
gChecker = GChecker()
gChecker.someStuff() # which uses urllib
My intention is to be able to run main.py file and call instantiate the classes under the checker/ directory. But I would like to avoid importing urllib from each file (if it is possible).
Note that both the __init__.py are empty files.
I have already tried calling from checker.gChecker import GChecker in main.py but a ImportError: No module named checker.gChecker shows.
In the posted code, in gChecker.py, you need to do
from baseChecker import BaseChecker
instead of import baseChecker
Otherwise you get
NameError: name 'BaseChecker' is not defined
Also with the mentioned folders structure you don't need checker module to be in the PYTHONPATH in order to be visible by main.py
Then in main.y you can do:
from checker import gChecker.GChecker

Categories

Resources