Alex Julius
Alex Julius

Reputation: 43

Is there a way for a function inside a function to know variables passed into parent function

I have two python functions, where one function uses the other. I have to pass the same variable into both. Instead of explicitly passing the variable in twice, is there a way for the second function to know the variables passed into the first?

Right now, I pass the variable in as input to the first function and it is passed into the second function.

The structure of my current code is:

def DB_Connection(source):

    conn = pyodbc.connect(dsn=source)

    return conn


def DB_Query(source, sql_string):

    conn = DB_Connection(source)
    data = pd.read_sql(sql_string, conn)

    return data

This works as expected; however, I didn't know whether it was the best practice. Instead, is there a way to do the following, where DB_Connection() knows source because it was passed into DB_Query():

def DB_Connection(source):

    conn = pyodbc.connect(dsn=source)

    return conn


def DB_Query(source, sql_string):

    conn = DB_Connection()
    data = pd.read_sql(sql_string, conn)

    return data

Upvotes: 1

Views: 146

Answers (5)

Tojra
Tojra

Reputation: 683

For doing this you need to change a bit the way your function code is implemented. So one thing you can do is call the second function inside the first. So that the variable is passed from first function to which value has been passed earlier(called earlier). Another approach,(although not so good) will be to use nested functions. Then even no need to pass value in Second function which is defined inside. A third approach would be to have the variable as global.

Upvotes: 0

Nevus
Nevus

Reputation: 1417

Anything passes to DB_Query can be passed (again) to DB_Connection as you have done in your example. As for DB_Connection automatically receiving parameter, its impossible. It would be possible if parameter to DB_Connection is constant/global variable which it can access.

Upvotes: 0

Charlie Hill
Charlie Hill

Reputation: 143

You could use a global variable:

global_source = None

def DB_Connection():

    source = global_source
    conn = pyodbc.connect(dsn=source)

    return conn


def DB_Query(source, sql_string):

    global global_source
    global_source = source

    conn = DB_Connection()
    data = pd.read_sql(sql_string, conn)

    return data

Upvotes: 0

chepner
chepner

Reputation: 531315

This is one of the use cases for a class, to share data between methods.

class DBConnection:
    def __init__(self, source):
        self.source = source

    def get_connection(self):
        return pyodbc.connect(dsn=self.source)

    def query(self, sql_string):
        return pd.read_sql(sql_string, self.get_connection())


db = DBConnection(...)
db.query("SELECT foo from bar")

This class also makes it easier to share a single connection between queries, rather than having query open a new connection each time.

class DBConnection:
    def __init__(self, source):
        self.source = pyodbc.connect(dsn=source)

    def get_connection(self):
        return self.source

    def query(self, sql_string):
        return pd.read_sql(sql_string, self.source)

Upvotes: 2

Kevin
Kevin

Reputation: 76194

One possible solution is to define DB_Connection inside the body of DB_Query. Then DB_Connection will automatically have access to all variables local to DB_Query.

def DB_Query(source, sql_string):

    def DB_Connection():
        conn = pyodbc.connect(dsn=source)
        return conn

    conn = DB_Connection()
    data = pd.read_sql(sql_string, conn)

    return data

The drawback is that DB_Connection will be inaccessible everywhere else in your code. So this is only an appropriate solution if DB_Query is the only context interested in calling DB_Connection.

Upvotes: 2

Related Questions