i'm a newbee at python and i'm having this error when importing class from a file this is my directory
-*
-- access.py
-- alloweds.py
in my acces.py i have this (is not all the complete code)
from alloweds import clasifier, record_user
conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='python')
cursor=conn.cursor()
uuid_id = uuid.uuid1()
alloweds=clasifier()
record = record_user()
and in my alloweds.py
from access import cursor
class clasifier():
def __init__(self):
self.Invited=['Test']
def verify(self,name):
if name in self.Invited:
return('Accept')
else:
return('Deny')
class record_user():
##code
and this is the error log
Traceback (most recent call last):
File ".\access.py", line 9, in <module>
from listaPermitidos import clasifier, record_user
File "C:\Users\rbnvl\alloweds.py", line 3, in <module>
from access import cursor
File "C:\Users\rbnvl\access.py", line 9, in <module>
from alloweds import clasifier, record_user
ImportError: cannot import name 'clasifier' from 'alloweds' (C:\Users\rbnvl\alloweds.py)
-
You have a circular import. Don't do that. The easiest way to fix this is to put the code that would depend on each other in the same module. Python isn't java, don't put every class in it's own file. Python uses modules as units of code organization, not classes.juanpa.arrivillaga– juanpa.arrivillaga2020年04月27日 05:16:16 +00:00Commented Apr 27, 2020 at 5:16
5 Answers 5
That is circular depency. Create one more file, for example database.py where you import your cursor.
# database.py
conn = MySQLdb.connect(host='localhost', user='root', passwd='', db='python')
cursor=conn.cursor()
# alloweds.py
from database import cursor
...
# access.py
from alloweds import clasifier, record_user
from database import cursor
...
5 Comments
allowed module depends on a global that is unneeded and can very easily avoided ;-) - passing depencencies as arguments is certainly not "beyond askers ability" (else they have another much more urgent issue to solve xD).You have a loop when you are importing from both files. So if you have only 1 file import from the other you should be fine.
Comments
As already mentionned, your issue comes from a circular dependencie - both modules depend on each other - which is both a general design issue (you should not have circular dependencies, whatever the language used) and badly supported by Python.
While there are quick'n'dirty technical workarounds those only mask the symptom, they don't cure the issue itself. There are various strategies to avoid circular dependencies (like extracting the common dependency to a distinct module as in ex4's answer), and most often you use a combination of thise. In your case, the very obvious issue is that you make your allowed module dependent on a global cursor for no good reason. What you should do here is, plain simply, to explicitely pass the dependee as argument to the depender ie:
class Depender():
def __init__(self, dependee):
self.dependee = dependee
def dothis(self, arg):
return self.dependee.do_something_with(arg)
This strategy (named "dependency injection") not only breaks the circular dependency, but also makes your code much more easily testable in isolation.
Now there's another - unrelated but severe - issue with your code: your allowed module's code should not depend on a cursor but on the connection object itself. The first and main reason is that cursors are not reentrant so if one function uses the cursor to iterate over a select query issue, and during the iteration calls another function that uses the same cursor for any other operation, you'll get very unexpected results. Also, you'll still need the connection object to handle transactions. Database connections are costly, but cursors are cheap disposable objects, so there's no good reason to try and reuse a cursor.
Comments
In youe access.py try,
from alloweds.classifier import classifier
from alloweds.recode_user import recode_user
This works if the both file in same directory. but if those are in different directories it will not work. If you want to import classes from different level of directories you have to import them through main.py
2 Comments
You cannot import two files vice versa, like, from class1 import Class1 in script 2 and from class2 import Class2 in script 1.