I use Python 2.7. I'm trying to run my UI-automation script, but I got ImportError.
I have at least 30 Classes with methods. I want to have these methods in each and any class that's why I created BaseClass(MainClass) and created objects of all my classes. Please advise what should I do in this case or how I can solve this problem.
Here the example what similar to my code.
test_class/baseclass.py
from test_class.first_class import FirstClass
from test_class.second_class import SecondClass
class MainClass:
def __init__(self):
self.firstclass = FirstClass()
self.secondclass = SecondClass()
test_class/first_class.py
from test_class.baseclass import MainClass
class FirstClass(MainClass):
def __init__(self):
MainClass.__init__(self)
def add_two_number(self):
return 2 + 2
test_class/second_class.py
from test_class.baseclass import MainClass
class SecondClass(MainClass):
def __init__(self):
MainClass.__init__(self)
def minus_number(self):
return self.firstclass.add_two_number() - 10
if __name__ == '__main__':
print(SecondClass().minus_number())
When I run the last file I get this error
Traceback (most recent call last):
File "/Users/nik-edcast/git/ui-automation/test_class/second_class.py", line 1, in <module>
from test_class.baseclass import MainClass
File "/Users/nik-edcast/git/ui-automation/test_class/baseclass.py", line 1, in <module>
from test_class.first_class import FirstClass
File "/Users/nik-edcast/git/ui-automation/test_class/first_class.py", line 1, in <module>
from test_class.baseclass import MainClass
ImportError: cannot import name MainClass
check this line: from test_class.baseclass import MainClass -> it seems like all other imports had a '_' between the names like second_class. So try maybe to write base_class. who knows might work
Are you proabably running your code like python test_class/second_class.py. If you just do this then python will think the base directory to find modules is ./test_class. So when you import the test_class package python will start looking for a folder called ./test_class/test_class to find the sub-modules. This directory doesn't exist and so the import fails. There are several ways that you can tell python how to correctly find your modules.
Using PYTHONPATH
One way to get around this is to set PYTHONPATH before starting python. This is just an environment variable with which you can tell python where to look for your modules.
eg.
export PYTHONPATH=/path/to/your/root/folder
python test_class/second_class.py
Using the -m switch for python
Be default python treats the directory of the main module as the place to look for other modules. However, if you use -m python will fall back to looking in the current directory. But you also need to specify the full name of the module you want to run (rather than as a file). eg.
python -m test_class.second_class
Writing a root entry point
In this we just define your main module at the base level (the directory that contains test_class. Python will treat this folder as the place to look for user modules and will find everything appropriately. eg.
main.py (in /path/to/your/root/folder)
from test_class.second_class import SecondClass
if __name__ == '__main__':
print(SecondClass().minus_number())
at the command line
python main.py
You could try importing the full files instead of using from file import class. Then you would only need to add the file name before referencing something from another file.
Related
I was working on a project with this type of folder tree:
-main.py
-Message_handlers
-__init__.py
-On_message.py
-Other_modules.py
-Exceptions_handler
-__init__.py
-Run_as_mainException.py
Message_handlers and Exceptions_handler are two packages, now my problem is that from inside the module On_message.py I can't import the class Run_as_mainException (inside of the module Run_as_mainException.py) using this code
# This is On_message.py
from ..Exceptions_handler.Run_as_mainException import Run_as_main_Exception
This line gives the error: ImportError: attempted relative import with no known parent package
p.s. Every file has a class inside with the same name of the file, example:
# This is Run_as_mainExample.py
class Run_as_mainExample:
def __init__(self):
# rest of the code
Can anyone help me please?
You have to assume that you're running everything from the level where main.py is located. This means, imagine that you execute python main.py, and you want to import Run_as_main_Exception from main.py, what should you do?
from Exceptions_handler.Run_as_mainException import Run_as_main_Exception
Try using that line in your On_message.py file, and you shouldn't have any problem when running your script from that exact location (remember, the same level where main.py is located)
In my main directory I have two programs: main.py and a myfolder (which is a directory).
The main.py file has these 2 lines:
from myfolder import Adding
print(Adding.execute())
Inside the myfolder directory, I have 3 python files only: __init__.py, abstract_math_ops.py, and adding.py.
The __init__.py file as just one line:
from myfolder.adding import Adding
The abstract_math_ops.py file is just an abstract class with one method:
from abc import ABC, abstractmethod
class AbstractMathOps(ABC):
#staticmethod
#abstractmethod
def execute(*args):
pass
The adding.py file is:
from abstract_math_ops import AbstractMathOps
class Adding(AbstractMathOps):
#staticmethod
def execute(*args):
--doing some addition --
When I execute main.py, I get the error:
~\myfolder\adding.py in <module>
---> 1 from abstract_math_ops import AbstractMathOps
ModuleNotFoundError: No module named 'abstract_math_ops '
If I put the abstract class inside the adding.py file, I do not get any errors. However, I need to put it in a different file as other python files (i.e. substracting.py, multipying.py) can be created following the footprint of the AbstractMathOps abstract class. Also, that way I do not have everything in a single file.
How can I solve this problem?
Your folder is a package, and you can't import sibling-submodules of a package in the way you're trying to do in adding.py. You either need to use an absolute import (from myfolder.abstract_math_ops import AbstractMathOps, which works the same anywhere), or use an explicit relative import (from .abstract_math_ops import AbstractMathOps, which only works from within the same package).
But if the two modules in your package are really as short as you've shown, maybe you should reconsider making myfolder a package at all. You could very easily define all of your classes in single myfolder.py file, and it would be easier to make sense of since the classes are so interrelated.
Try with:
from .abstract_math_ops import AbstractMathOps
You need to add the relative location of the file for the import to work in this case.
My first question on stack! :D
I have a problem when I try to have my cake and eat it too, it seems.
I have stripped out all the code as I do not believe that it is part of the problem.
I have the following dir structure:
master/
- main.py
- modules/
- parent_class.py
- child_class.py
- __init__.py
In parent_class.py:
class Parent:
pass
In child_class.py:
from modules.parent_class import Parent
class Child(Parent)
pass
if __name__ == "__main__":
child = Child()
child.do_stuff()
In main.py:
from modules.child_class import Child
child = Child()
child.do_stuff()
The problem I am having I believe it has to do with me not understanding sys.path properly.
When I run main.py there are no errors.
However, when I try to run child_class.py for testing purposes I get the following error...
Traceback (most recent call last):
File "child_class.py", line 1, in <module>
from modules.parent_class import Parent
ModuleNotFoundError: No module named 'modules'
The error goes away when I change child_class.py to this:
from parent_class import Parent
class Child(Parent)
pass
if __name__ == "__main__":
child = Child()
child.do_stuff()
But now when I run main.py I get this error:
Traceback (most recent call last):
File "c.../main.py", line 1, in <module>
from modules.child_class import Child
File "...\child_class.py", line 1, in <module>
from parent_class import Parent
ModuleNotFoundError: No module named 'parent_class'
How do you do a unit test if you have to change the import line every time?
Thank you in advance for a good explaination. (I have read a lot of docs on importing, and packages and modules, watched like 10 different vids on this topic but still not sure why or how to make this just work.) (I am just saying I have tried to find the answer, but I am now exhausted and need a solution before I really go mad!) thank you, thank you, thank you
TLDR:
Run the python file with the -m flag.
python -m modules.child_class
This issue is a result of misunderstanding the difference between Python Script programs and Python Package programs.
If you are running a Python program as a script (running a Python file directly), then you do direct imports like you have already:
from parent_class import Parent
However, if you are building a Python Package that is designed for importing into other programs (eg. a Library or Framework) then you need to use relative imports. (Sounds like the Unittest is running the program as a package but when you run the program, you are running it as a script.)
from .parent_class import Parent
# or
from modules.parent_class import Parent
If you are making a package then run the program with the -m flag or import into another program (a script or another package)
python -m main
or
python -m modules.child_class
Until someone shows me a better way, I will do the following...
if __name__ == "__main__":
from parent_class import Parent
else:
from modules.parent_class import Parent
I have a custom Python library ("common") that is being imported and used from several Python projects.
That central library has the following structure:
/common
/__init__.py
/wrapper.py
/util
/__init__.py
/misc.py
Our custom library resides in a central place /data/Development/Python, so in my Python projects I have an .env file in order to include our lib:
PYTHONPATH="/data/Development/Python"
That works fine, I can for example do something like:
from common.util import misc
However, now I want to make use of a class MyClass within common/wrapper.py from the code in common/util/misc.py. Thus I tried the following import in misc.py:
from ..wrapper import MyClass
But that leads to the following error:
Exception has occurred: ImportError
cannot import name 'MyClass'
Any ideas what I am doing wrong here?
PS: When I do an from .. import wrapper instead and then from code I use wrapper.MyClass, then it works fine. Does that make any sense?
It's finding wrapper, otherwise you'd get a different error:
>>> from wibble import myclass
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'wibble'
So it seems wrapper does not contain MyClass. Typo?
"However, now I want to make use of a class MyClass within common/wrapper.py from the code in common/util/misc.py. Thus I tried the following import in misc.py:"
If you do export PYTHONPATH=~/common
In order to import MyClass you will do:
from wrapper import MyClass
Because you have added common to your root folder, utils is already in your path since it is in you root folder.
Similarly, if you wanted to import from wrapper you would do from utils.misc import ThisClass since utils.misc is already in the root folder common
I am having a problem that may be quite a basic thing, but as a Python learner I've been struggling with it for hours. The documentation has not provided me with an answer so far.
The problem is that an import statement included in a module does not seem to be executed when I import this module from a python script. What I have is as follows:
I have a file project.py (i.e. python library) that looks like this:
import datetime
class Project:
""" This class is a container for project data """
title = ""
manager = ""
date = datetime.datetime.min
def __init__( self, title="", manager="", date=datetime.datetime.min ):
""" Init function with some defaults """
self.title = title
self.manager = manager
self.date = date
This library is later used in a script (file.py) that imports project, it starts like this:
import project
print datetime.datetime.min
The problem then arises when I try to execute this script with Python file.py. Python then complains with the folliwing NameError:
Traceback (most recent call last):
File "file.py", line 3, in <module>
print datetime.datetime.min
NameError: name 'datetime' is not defined
This actually happens also if I try to make the same statements (import and print) directly from the Python shell.
Shouldn't the datetime module be automatically imported in the precise moment that I call import project?
Thanks a lot in advance.
The datetime module is only imported into the project namespace. So you could access it as project.datetime.datetime.min, but really you should import it into your script directly.
Every symbol (name) that you create in your project.py file (like your Project class) ends up in the project namespace, which includes things you import from other modules. This isn't as inefficient as it might seem however - the actual datetime module is still only imported once, no matter how many times you do it. Every time you import it subsequent to the first one it's just importing the names into the current namespace, but not actually doing all the heavy lifting of reading and importing the module.
Try thinking of the import statement as roughly equivalent to:
project = __import__('project')
Effectively an import statement is simply an assignment to a variable. There may be some side effects as the module is loaded, but from inside your script all you see is a simple assignment to a name.
You can pull in all the names from a module using from project import *, but don't do that because it makes your code much more brittle and harder to maintain. Instead either just import the module or exactly the names you want.
So for your code something like:
import datetime
from project import Project
is the sort of thing you should be doing.