This works okay (some code ommited for brevity):
# main.py
cursor = db.cursor()
cursor.execute('foo')
As does this:
# other.py
def do_something(script, cursor):
cursor.execute(script)
# main.py
from other import do_something
cursor = db.cursor()
do_something('foo', cursor)
But (as I understand it) the "lower" scope of the function should be able to access the "higher" (global?) scoped cursor - why should I need to pass the cursor as an argument on my function? So I tried this:
# other.py
def do_something(script):
cursor.execute(script)
# main.py
from other import do_something
cursor = db.cursor()
do_something('foo')
Which returns:
NameError: global name 'cursor' is not defined
I thought "maybe running a query against the cursor is a write operation, not a read" and tried:
# other.py
def do_something(script):
global cursor
cursor.execute(script)
# main.py
from other import do_something
cursor = db.cursor()
do_something('foo')
Same error. What am I missing?
EDIT: It sounds like "how do I make variable names global across different modules" is the wrong question. The right question - if I have a primary handler, a SQL cursor and a file of common functions, how should I structure my files / imports?
try this code
# other.py
def do_something(script):
global cursor
cursor.execute(script)
# main.py
from other import do_something
import other
other.cursor = db.cursor()
do_something(script)
My English is not good, so you can read these answers
Global Variable from a different file Python
Using global variables between files?
make variable global to multiple files in python
Related
I am trying out a Tkinter project that allows users to fill in a form. The file name with the variable (cur_user) which I need is named login.py and the variable is found in the class Login_Window and under a function below. I used "from login import Login_Window" and called the function with Login_Window.cur_user but it gives me an error saying that (type object 'Login_Window' has no attribute 'cur_user'). How do I solve this?
def login(self):
global cur_user
if self.txtuser.get() == "" or self.txtpass.get() == "":
messagebox.showerror("Required", "Please enter username and password")
else:
conn = mysql.connector.connect(host="localhost", user="root", password="assessment", database="sys")
cur = conn.cursor()
query = ("select userID from iadata where username=%s")
value = (self.user_var.get(),)
cur.execute(query,value)
row= cur.fetchone()
cur_user=row[0]
# print(cur_user)
How do I use a variable that is inside a class of one file in another file?
As the question stands, the answer is not that complicated:
# module.py
class Values: # In this case the class is used in a way similar to a namespace
variable = 42
# main.py
import module
print(module.Values.variable) # 42
I have a few files in my code that speak to the database
This might look something like this:
def addUser():
# some code
def verifyUser():
# some code
def addStuffToDB():
# some code
In all of the above I need to use a variable - let's call it db - that holds a reference to the database (as opposed to redefining it in every function)
How would I do this? How can I have functions in one or more files that all make use of a variable (in this case db)
Thanks
If you have all this functions inside the same file, it is enough to just define variable db outside any function (this will make it global). Now all functions will be able to see db variable. But if you change db inside a function it will not change outside the function.
If you have this variable in another file you can simple import it like
from file_name import db
As #ddejohn said, you should wrap your functions in a class, so the variable self.db would have a class scope.
class DB():
def __init__(self) -> None:
self.db = "DB_connection or something..."
def addUser(self):
#Some code, acess db variable with self.db
def verifyUser(self):
#Some code, acess db variable with self.db
def addStuffToDB(self):
#Some code, acess db variable with self.db
MyDB = DB()
MyDB.addUser()
Thanks for asking the question.
You need to pass db as argument while calling the funcs like the following
db = "some referenec"
def addUser(database):
## now you can use db
# some code
def verifyUser(database):
# some code
## now you can use db
def addStuffToDB(database):
# some code
## now you can use db
## while calling each func pass db as argument like this
addUser(db)
verifyUser(db)
addStuffToDB(db)
add a db paramenter to yout funcs:
controller.py:
def addUser(db): # some code
obj.add(db)
def verifyUser(db): # some code
obj.verify(db)
def addStuffToDB(db): # some code
obj.add_stuff(db)
Then, you can use as follows:
view.py
import db
from controller import addUser
addUser(db)
I'm programming in Sublime Text 3 and I need to use an object-oriented class in another class and I can't reach it and its functions from another class (I saved them both on the same directory on my computer), thanks for the helpers.
If I understand you correctly, I think you're trying to access one python module from another python module (each "module" is a file), and each module contains a class.
If class A is Foo, saved in foo.py, and class B is Bar saved in bar.py, and you want to use Foo inside of Bar, then you need to import Foo such that it is in scope when Bar is defined.
You might try, in bar.py, above where Bar is defined: from foo import Foo
For more information, this might help: https://docs.python.org/3/tutorial/modules.html
class1:
import sqlite3
from driver import Driver
from sqlitte import error
def create():
try:
conn = sqlite3.connect(':memory:')
except error as e:
print (e)
c = conn.cursor()
c.excute("""CREATE TABLE users(
price real,
discount real
)""")
conn.commit()
conn.close()
and class 2(saved in the same directory as driver.py):
class Driver:
def __init__(self, online_id):
self.online_id = online_id
def get_online_id():
return self.online_id
What is the best way to expose a variable from a module?
import otherDBInterface as odbi
def create(host):
global connection
global cursor
connection = odbi.connect(host)
cursor = connection.cursor()
...
I want to expose the cursor variable in the module so I can do something like mydb.cursor.execute("select * from foo;"). I thought using the global keyword would do this but no such luck. cursor is an object so I am not sure how I would declare it so that it would be exposed.
You can wrap your connection information in a class
class Database:
def __init__(self, **kwargs):
if kwargs.get("connection") is not None:
self.connection = kwargs["connection"]
elif kwargs.get("host") is not None:
self.connection = odbi.connect(host)
self.cursor = self.connection.cursor()
mydb = Database(host="localhost")
results = mydb.cursor.execute("select * from foo")
#or use it with a connection
mydb = Database(connection="localhost")
results = mydb.cursor.execute("select * from foo")
Any variable created on a module level is "exposed" by default.
Hence, a module like this will have three exposed variables:
configpath = '$HOME/.config'
class Configuration(object):
def __init__(self, configpath):
self.configfile = open(configpath, 'rb')
config = Configuration(configpath)
The variables are configpath, Configuration and config. All of these are importable from other modules. You can also access configs configfile as config.configfile.
You can also have configfile accessible globally this way:
configpath = '$HOME/.config'
configfile = None
class Configuration(object):
def __init__(self, configpath):
global configfile
configfile = open(configpath, 'rb')
config = Configuration(configpath)
But there are various tricky problems with this, as if you get a handle on configfile from another module and it then gets replaced from within Configuration your original handle will not change. Therefore this only works with mutable objects.
In the above example that means that using configfile as a global in this way will not be very useful. However, using config like that could work well.
Noobish question to be sure. I have tried to move some common code into a separate module and use the code as an imported function. The code makes a MySQL query through MySQLdb. When the function is part of the main script, it runs just fine. When I import the function from a separate module, the function fails because the cursor object is no longer defined. Is there a way to import functions without defining a separate cursor object for just the imported function?
Here is an coded example. This works:
import MySQLdb
#from mod2 import lookup_value
def get_db_connection(database_name):
db = MySQLdb.connect('localhost', 'user', 'pswrd', database_name)
cur = db.cursor()
return db, cur
def lookup_value(user_name):
query = "SELECT COUNT(*) FROM x_user_%s" % (user_name)
cur.execute("%s" % (query))
return cur.fetchone()
db_name = 'mg_test' # database name
user_name = 'test' # name of a specific table in the database
db, cur = get_db_connection(db_name)
value = lookup_value(user_name)
When I move the code for lookup_value to a second file, and import it ('from mod2 import lookup_value'), the code fails because the cursor object is undefined. The imported version of lookup_value only works if I create a cursor object for its use. This seems very inefficient. What is the best way to handle this problem?
That's because lookup_value searches for the cur within the file you import it in. You could put this all in a class.
class DB():
def __init__(self,database_name):
db = MySQLdb.connect('localhost', 'user', 'pswrd', database_name)
self.cur = db.cursor()
def lookup_value(self,user_name):
query = "SELECT COUNT(*) FROM x_user_%s"
self.cur.execute(query, (user_name,))
self.result = self.cur.fetchone()
return self.result
now you can do
....
db = DB(db_name)
value = db.lookup_value(user_name)
when you import the DB from mod2 import DB the last part should still work.
Also take note of how i execute the query in lookup_value this ensures the data is sanitized
You should pass a cursor variable to your functions if you want them to be independent.
In any case you should use in a function only local variables and variables passed as parameters.