python 3.4: Cannot import class from another file - python

A question like this has appeared multiple times here, but none of the answers have worked for me. I'm using Python 3.4 with PyCharm as my IDE. In file make_layers.py, I have the following little placeholder of a class (np is my imported numpy):
class Finder:
def __init__(self):
pass
def get_next_shape(self, uses_left):
mask = np.zeros(uses_left.shape, dtype=np.int16)
return mask
In another file in the same directory, box_finder.py, I try to import the class and make a subclass:
import make_layers as ml
class BoxFinder(ml.Finder):
def __init__(self):
pass
When I try to run this, it fails at the import statement, saying
AttributeError: module 'make_layers' has no attribute 'Finder'
I've tried endless variations on the syntax (including things like from make_layers import Finder), but nothing works. It must be something obvious, but I can't see the problem. Any help would be appreciated!
EDIT: Antti, you nailed it. There was a sneaky circular import in there. I moved Finder to its own file, and success! Thank you everyone!

Your modules look correct, and should work.
The most likely source of error is that another file called make_layers.py is being imported. To check this, print ml.__file__ to see where the make_layers module is being imported from.

If you are on Linux, to import your own classes you need to put them into your $PYTHONPATH environment variable.
export PYTHONPATH=$PYTHONPATH:/where/the/file/is
If this is the case i would suggest to put this line in your .bashrc to avoid doing the export in after every restart
Second, to make PyCharm recognise the importable classes from your script you have to mark the directory as sources root. After this PyCharm should see that you have a Finder class inml

Related

Python Can't Import Class From Parent Directory?

I am new to Python, so I might not be seeing the obvious solution to this. I have searched online for a solution and everyone seems to have the same answer. I am trying to import a file from a parent directory in Python. I am coming from JavaScript where you simply type import Function from '../ParenetDirectory/FileThatIncludesFunction' and you can import that module. Every website I have visited says you have to include the parent directory in your freakin' path to import it. Are we serious here? I assume I am missing something because it seems to me that Python would have a more elegant way to do this than editing your freaking path to import a class from a parent directory. Please tell me it does, or explain to me why it doesn't.
You can do this by using the sys module and adding the desired directory to its path.
"../ParenetDirectory/FileThatIncludesFunction.py" :
def Function():
return 'Hello, World!'
main.py :
import sys
sys.path.append('../ParenetDirectory')
from FileThatIncludesFunction import Function
print(Function())
Note that if you want to run this via cmd, make sure that the folder in cmd is exactly where the main.py file is located.

Importing packages works but still get errors?

I have a Python application that conforms to the MVC model so I have folders called Controller, Model and View. In each of these folders I have Python files that I import into each other. It seems to work however when you hover the cursor over the import I see the "Unable to import XXXX" error and I am not sure why this is.
I have an empty __init__ file in each folder and have added the path to system path.
The directory of my application goes like this:
Desktop/Application--¬
Controller--¬
MainController.py
GraphEngine.py
APIMethods.py
Model-------¬
MainModel.py
DatabaseAccess.py
View
I use import sys
sys.path.append('C:/Users/XXXX/Desktop/Data-Processing-Engine-Sorted/Controller')
to set the system path and then use import MainController to actually gain access to the file.
This seems to work fine. The other file locates MainController and uses its methods with no issue, however in the IDE I can't get rid of the "Unable to import MainController" error. I am really quite confused as to why.
Thanks for your help in advance.
I found out the issue! It's very simple and quite embarrassing...
When calling one of the methods I was only calling the module rather than the class, for example:
controller = MainController() Would return with an error while
controller = MainController.MainController() Would create an instance of my class

Python: After initialising a module, no longer can import functions

I have two files: 'my_main.py' and 'my_functions.py'. I wrote two functions in 'my_functions.py', 'first_function' and 'second_function' and imported this module into 'my_main.py'. However, I then added a third function into 'my_functions.py' called 'third_function':
def first_function():
print("hello1")
def second_function():
print("hello2")
def third_function():
print("hello3")
I found that I could not import 'third_function' into 'my_main.py', getting an error - AttributeError: module 'my_functions' has no attribute 'third_function'.
To understand this, in 'my_main.py' I then ran:
import my_functions
help(my_functions)
and had as my output:
Help on module my_functions:
NAME
my_functions
FUNCTIONS
first_function()
second_function()
For some reason 'my_functions.py' would not recognise any more functions after the initial two, meaning I couldn't then import 'third_function' into 'my_main.py'. How can I fix this?
Make sure you have saved your file my_functions.py before running my_main.py. Unless the file is saved, the update (addition of third_function) won't be recognized. Have been doing this for years, and still make this mistake constantly. Editing not enough. Need to edit and save.
You need to explicitly reload the module if you've made changes since the last import. There is a built-in function for this
You can reload your module as follows:
import importlib
importlib.reload(my_functions)
See this answer for a much more detailed explanation.

Cannot import local module in Python despite trying multiple suggestions

I've read through about ten posts on how to import local modules, and I'm still stumped on why this isn't working. I have an extremely simple module, actor.py, with a single class inside it:
class Actor(object):
def __init__(self, name, age):
self.name = name
self.age = age
I'm trying to import it into another module, scraper.py, within the same directory:
Some fixes have listed not having init.py as being a problem with local imports, so I know that's not my problem.
Initially I tried these:
import actor
and
from actor import Actor
but it tells me that actor and Actor are unresolved references. here tells me that's Python 2 syntax, and I'm using Python 3. That answer instead recommends that I do:
from .actor import Actor
When I run my program with that syntax, I get this error:
ModuleNotFoundError: No module named '__main__.actor'; '__main__' is not a package
So I go searching again, and this post tells me to remove the dot from 'actor,' but as stated before, I've tried that as well. My final guess was
from . import actor
but that yields
ImportError: cannot import name 'actor'
which I follow to here, but the answers there mention circular dependencies, and I'm certain actor and scraper have none. Am I perhaps not writing my module correctly? I can't think of any other ways to write an import statement.
edit: if it helps at all, I'm using Intellij
Try from WebScraper.actor import Actor. If this doesn't work its because your package directory is not in the PYTHONPATH. You can set that in the IntelliJ Python run configuration.
The relative import is not working for you because you are trying to run a module as a script. You can see an explanation of what is happening at https://stackoverflow.com/a/8300343/7088038. If you want relative imports to work you will have to add a __main__.py file to your module to allow it to be runnable, or execute from an external script where you use an absolute import so you don't clobber the package namespace.
One other stylistic note- usually (but not always) package names in python use all lowercase names. CamelCase is reserved for class names. So if you wanted to follow convention you would call your package webscraper and use from webscraper.actor import Actor
To import a class into your script use:
from actor import Actor
Or to import the .py entirely (including whatever imports included in it) into the namespace use:
from actor import *

Linking Python Files Assistance

I understand how to actually link python files, however, i don't understand how to get variable's from these linked files. I've tried to grab them and I keep getting NameError.
How do I go about doing this? The reason i want to link files is to simply neaten up my script and not make it 10000000000 lines long. Also, in the imported python script, do i have to import everything again? Another question, do i use the self function when using another scripts functions?
ie;
Main Script:
import sys, os
import importedpyfile
Imported Py File
import sys, os
I understand how to actually link python files, however, i don't
understand how to get variable's from these linked files. I've tried
to grab them and I keep getting NameError.
How are you doing that? Post more code. For instance, the following works:
file1.py
#!/usr/bin/env python
from file2 import file2_func, file2_variable
file2_func()
print file2_variable
file2.py:
#!/usr/bin/env python
file2_variable = "I'm a variable!"
def file2_func():
print "Hello World!"
Also, in the imported python script, do i have to import everything
again?
Nope, modules should be imported when the python interpreter reads that file.
Another question, do i use the self function when using another
scripts functions?
Nope, that's usually to access class members. See python self explained.
There is also more than one way to import files. See the other answer for some explanations.
I think what you are trying to ask is how to get access to global vars from on .py file without having to deal with namespaces.
In your main script, replace the call to import importedpyfile to say this instead
from importedpyfile import *
Ideally, you keep the code the way you have it. But instead, just reference those global vars with the importedpyfile namespace.
e.g.
import importedpyfile
importedpyfile.MyFunction() # calls "MyFunction" that is defined in importedpyfile.py
Python modules are not "linked" in the sense of C/C++ linking libraries into an executable. A Python import operation creates a name that refers to the imported module; without this name there is no (direct) way to access another module.

Categories