2

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.

4
  • 1
    That should do it, but obviously you'll need to call the create function before cursor will exist. Can you show the code where you try to import/use the cursor object? Commented Jun 28, 2013 at 3:47
  • Is mydb is module name? Commented Jun 28, 2013 at 4:45
  • Yes, in this example, mydb is the module name. Commented Jun 28, 2013 at 5:02
  • BrenBarm, I figured it out. I have two "constructors" in this module and one of them wasn't setting cursor. I changed it to do that and now it works. Commented Jun 28, 2013 at 5:19

2 Answers 2

5

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")
Sign up to request clarification or add additional context in comments.

3 Comments

+1 to counter the unexplained anonymous downvote. Encapsulating in an object is vastly better than a global variable, and usually more correct to boot.
Is there a way to have two "constructors" in a Python class? I need a connect() constructor to connect to an existing database and a create() constructor to build a database from scratch.
What you are asking for is called method overloading and languages like Java have that, but not Python. In Python you would use dynamic arguments.
2

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.