Import class from another file - python

I know this question has been asked before, but none of the given answers worked. Say I have a file named Test.py with this code:
class Test():
def __init__(self):
print('Instance Created')
I want to use this class in another file, say Test2.py.
I used the path to the file to get the class, but the message attempted relative import with no known parent package pops up
.
I am using IDLE on Mac OS X.
The path to the file is /Users/*name*/Desktop/Code/Test.py, where *name* is my username for this device.
Code in Test2.py:
from .Users.*name*.Desktop.Code.Test import Test
When I run the program, this message comes up:
Traceback (most recent call last):
File "/Users/*name*/Desktop/Code/Test2.py", line 1, in <module>
from .Users.owen.Desktop.Code.Test import Test
ImportError: attempted relative import with no known parent package
I have tried using sys.path.append but it doesn't seem to work. I have also tried using just .Desktop or .Code instead of the full name, but this gives the same error. I researched packages online, but am struggling to fully comprehend what they are, much less make/use them. Any help would be greatly appreciated.

Related

Error with importing a class from a module

This is my first time asking a question so please excuse me.
I am following a tutorial and using the code in this folder: https://github.com/ehmatthes/pcc_2e/tree/master/chapter_12/adding_ship_image
I literally replicated this folder in vs code with all the code and the names being used correctly.
For some reason I am getting this error:
Traceback (most recent call last):
File "/Users/sammyawad/Documents/projects/alieninvasion/alien_invasion.py", line 6, in <module>
from ship import Ship
ImportError: cannot import name 'Ship' from 'ship' (/Users/sammyawad/Documents/projects/alieninvasion/ship.py)
Also, I think I have an issue with linting because it is highlighting the pygame init functions for the class even though it works.
Change it to:
from .ship import Ship
import module as instance of class like this...
from ship import Ship as s1

ImportError: cannot import name, even though I've every solution here

My file is named "foo.py". It has only two lines.
import random
print(random.randint(10))
The error is...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py", line 45, in <module>
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
File "math.py", line 2, in <module>
from random import randint
ImportError: cannot import name randint
I am on MacOS 10.14.6
I note that I did not call random.randint() in this script, even
though it showed up in the error text.
I ran the script with $python
My /usr/bin/python is linked to python 2.7
I've tried this with python 3 as well, with the same error.
EDIT:
My script was originally named "math.py", but I changed it in response to another solution that pointed out the name conflict with the math.py library (even though my script was not importing that library). Even after my script name change, I'm still seeing --File "math.py"-- errors. Even after I'm no longer using random.randint(), I'm still seeing that function referenced in my errors.
I've tried deleting random.pyc and math.pyc to purge the artifacts of previous executions. But these do not see to eliminate the remnants of earlier errors.
Read the traceback:
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/random.py"
Python tries to do something inside the standard library random module...
from math import log as _log, exp as _exp, pi as _pi, e as _e, ceil as _ceil
in particular, it tries to import the standard library math module...
File "math.py", line 2, in <module>
but it gets yours instead (notice there's no path on the filename this time; it's just math.py in the current directory); i.e. the script you started from. Python detects the circular import and fails:
ImportError: cannot import name randint
Actually using randint doesn't matter, because this is a problem with the actual import of the module.
This happens because Python is configured by default (using sys.path, which is a list of paths to try, in order) to try to import scripts from the current working directory before looking anywhere else. It's convenient when you just want to write a few source files in the same folder and have them work with each other, but it causes these problems.
The expected solution is to just rename your file. Unfortunately there isn't an obvious list of names to avoid, although you could peek at your installation folder to be sure (or just check the online library reference, though that's not quite so direct).
I guess you could also modify sys.path:
import sys
sys.path.remove('') # the empty string in this list is for the current directory
sys.path.append('') # put it back, at the end this time
import random # now Python will look for modules in the standard library first,
# and only in the current folder as a last resort.
However, this is an ugly hack. It might break something else (and it can't save you if you have a local sys.py).

How to import a file from a package which is importing another file from the same package

I've been working on a project where I have a file which needs to call a function from a file in a sub package/directory, which in turn is calling a function from another file in the same sub package. As such, I have a main file which is importing a sub file. This sub file is also importing another sub file which is in the same package.
The first sub file has no issue whatsoever importing the second sub file. The main file also has no issue importing the first sub file. However, when I put it all together and run the main file, Python thinks that the second sub file doesn't exist, which I find strange. I've simplified and visualised my problem with an example below:
I have the following file hierarchy:
test_package\
__init__.py
main_file.py
test_sub_package\
__init__.py
subfile1.py
subfile2.py
main_file code:
import test_sub_package.subfile1
subfile1 code:
import subfile2
subfile2 code:
def get_string():
return ("Hello, World!")
So, I would expect main_file to import subfile2 via subfile1. However this doesn't seem to be the case because I get an error:
Traceback (most recent call last):
File "...\Test\main_file.py", line 1, in <module>
import test_package.subfile1
File "...\Test\test_sub_package\subfile1.py", line 1, in <module>
import subfile2
ModuleNotFoundError: No module named 'subfile2'
I was a little surprised that I got this error before I even attempted to call the functionality in subfile2. Either way, I'm confused why this doesn't work. Am I just doing something stupid here or am I trying to do something Python fundamentally doesn't support. If anyone can give me a solution it would be most appreciated.
I suspect this is probably a duplicate but I couldn't find an answer to my specific problem. So, sorry in advance.
When you import a module into another module from the same directory you must use must use a relative import in subfile1.py you will need to write:
from . import subfile2
Note, that doesn't give subfile 1 access to get_string to use it in subfile1, you would need to either write subfile2.get_string() or import it directly with:
from .subfile2 import get_string
I have tried this out and it works, I hope this helps :)
Note: that, if you are running a python script, and you need to import a module in that same directory, you can just say import module_name. It makes a difference if it is a script you are running, or a module that is being used in some other script. For a detailed explanation as to why see here
(I assume from your error message that you want to run main.py, if this is not the case you will need to change import test_sub_package.subfile1 to from . import test_sub_package.subfile1)
main file should be:
from test_sub_package.subfile1 import get_string
get_string()
subfile1.py
import test_sub_package.subfile2

Python import error: 'module' object has no attribute 'x'

I am trying to do a python script that it is divided in multiple files, so I can maintain it more easily instead of making a very-long single file script.
Here is the directory structure:
wmlxgettext.py
<pywmlx>
|- __init__.py
|- (some other .py files)
|- <state>
|- __init__.py
|- state.py
|- machine.py
|- lua_idle.py
if I reach the main directory of my project (where the wmlxgettext.py script is stored) and if I try to "import pywmlx" I have an import error (Attribute Error: 'module' object has no attribute 'state')
Here is the complete error message:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/user/programmi/my/python/wmlxgettext/true/pywmlx/__init__.py", line 9, in <module>
import pywmlx.state as statemachine
File "/home/user/programmi/my/python/wmlxgettext/true/pywmlx/state/__init__.py", line 1, in <module>
from pywmlx.state.machine import setup
File "/home/user/programmi/my/python/wmlxgettext/true/pywmlx/state/machine.py", line 2, in <module>
from pywmlx.state.lua_idle import setup_luastates
File "/home/user/programmi/my/python/wmlxgettext/true/pywmlx/state/lua_idle.py", line 3, in <module>
import pywmlx.state.machine as statemachine
AttributeError: 'module' object has no attribute 'state'
Since I am in the "project main directory" pywmlx should be on PYTHONPATH (infact I have no troubles when I tried to import pywmlx/something.py)
I'm not able to figure where is my error and how to solve this problem.
Here is the pywmlx/__init__.py source:
# all following imports works well:
from pywmlx.wmlerr import ansi_setEnabled
from pywmlx.wmlerr import wmlerr
from pywmlx.wmlerr import wmlwarn
from pywmlx.postring import PoCommentedString
from pywmlx.postring import WmlNodeSentence
from pywmlx.postring import WmlNode
# this is the import that does not work:
import pywmlx.state as statemachine
Here is the pywmlx/state/__init__.py source:
from pywmlx.state.machine import setup
from pywmlx.state.machine import run
But I think that the real problem is somewhat hidden in the "imports" used by one (or all) python modules stored in pywmlx/state directory.
Here is the pywmlx/state/machine.py source:
# State is a "virtual" class
from pywmlx.state.state import State
from pywmlx.state.lua_idle import setup_luastates
import pywmlx.nodemanip as nodemanip
def addstate(self, name, value):
# code is not important for this question
pass
def setup():
setup_luastates()
def run(self, *, filebuf, fileref, fileno, startstate, waitwml=True):
# to do
pass
Finally here is the pywmlx/state/lua_idle.py source:
import re
import pywmlx.state.machine as statemachine
# State is a "virtual" class
from pywmlx.state.state import State
# every state is a subclass of State
# all proprieties were defined originally on the base State class:
# self.regex and self.iffail were "None"
# the body of "run" function was only "pass"
class LuaIdleState (State):
def __init__(self):
self.regex = re.compile(r'--.*?\s*#textdomain\s+(\S+)', re.I)
self.iffail = 'lua_checkpo'
def run(xline, match):
statemachine._currentdomain = match.group(1)
xline = None
return (xline, 'lua_idle')
def setup_luastates():
statemachine.addstate('lua_idle', LuaIdleState)
Sorry if I posted so much code and so many files... but I fear that the files, in directory, hides more than a single import problem, so I published them all, hoping that I could explain the problem avoiding confusion.
I think that I miss something about how import works in python, so I hope this question can be useful also to other programmers, becouse I think I am not the only one who found the official documentation very difficult to understand when explaining import.
Searches Done:
Not Useful: I am already explicitly using import x.y.z all times I need to import something
Not Useful: Even if the question asks about import errors, it seems not useful for the same reason as (1)
Not Useful: As far as I know, pywmlx should be located into PYTHONPATH since "current working directory" on my tests is the directory that contains the main python script and pywmlx directory. Correct me if I am wrong
Python does several things when importing packages:
Create an object in sys.modules for the package, with the name as key: 'pywmlx', 'pywmlx.state', 'pywmlx.state.machine', etc.
Run the bytecode loaded for that module; this may create more modules.
Once a module is fully loaded and it is located inside another package, set the module as an attribute of the parent module object. Thus the sys.modules['pywmlx.state'] module is set as the state attribute on the sys.modules['pywmlx'] module object.
That last step hasn't taken place yet in your example, but the following line only works when it has been set:
import pywmlx.state.machine as statemachine
because this looks up both state and machine as attributes first. Use this syntax instead:
from pywmlx.state import machine as statemachine
Alternatively, just use
import pywmlx.state.machine
and replace statemachine. everywhere else with pywmlx.state.machine.. This works because all that is added to your namespace is a reference to the sys.modules['pywmlx'] module object and the attribute references won't need to be resolved until you use that reference in the functions and methods.
You are having a circular import in your framework. Circular imports do not work well with aliases. When importing a module with an alias and then, during the circular import, importing it again without an alias, python complains. The solution is to not use aliases (the "import module as" syntax) but always use the full "import module" statement.

Python: cannot load class from my module

EDIT:
I couldn't use my own modules. It was a stupid waste of time. If you ever have the same problem, try reading this first:
http://docs.python-guide.org/en/latest/writing/structure/
I just started OOP with Python and I am confused by modules and classes.
I work with a Mac and I can write my own modules and load them from the site-packages folder.
Now I would like to create modules with useful classes.
import custom_module works.
But if custom_module has a class Custom_class, things don't work.
I tried doing:
(EDIT: I am sorry, I am removing old code which was made up, this is what I just used and doesn't work)
in custommodule.py:
class Customclass:
def __init__(self, name):
self.name = name
This module loads without errors.
Then I get:
new = custommodule.Customclass('foo')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'module' object has no attribute 'Customclass'
BTW, I started trying to do this using code from this tutorial
I was not able to get over this. Please advise, I must be doing something wrong.
With this file layout
site-packages/custommodule/__init__.py
site-packages/custommodule/custommodule.py
you are creating a package named custommodule that contains a module also named custommodule. Your code needs to look like
import custommodule
# or more specifically,
# import custommodule.custommodule
new = custommodule.custommodule.Customclass('foo')
or
from custommmodule import custommodule
new = custommodule.Customclass('foo')
You can also put custommodule.py directly in site-packages to avoid creating the package, in which case your original code should work.
For me, at least, this works from mod_name import ClassName
When I run this code I don't get any errors. Hope this helped
EDIT: also make sure that the module you want to import is in the project directory. If you view the left panel in the images both modules are in Stack. I hope this is obvious but, the class needs to be in the module you import as well. Make sure that the class you're importing does not import the class your importing in because then you get circular dependencies.
Try this way
File custommodule.py in the directory custommodule
class Customclass:
def __init__(self, name):
self.name = name
File __init__.py int he custommodule directory
from .custommodule import CustomClass
Note the dot before custommodule. This force the init to load the module from the same directory.
Without the dot, it work under python2 but not under python3

Categories

Resources