How to have Static and Method Functions with the same name

Question:

I’m trying to create a class for interacting with a MySQL Database. This class will connect to the database storing the connection object and cursor. Allowing for multiple actions without reconnecting every time. Once you’re done with it, the cursor and connection need to be closed. So I’ve implemented it as a context manager and it works great.

I need the support to be able to do multiple actions without reopening the connection each time, but most of the time I am only running one Query/command. So I end up having to write the below code to run a single query.

with MySQLConnector() as connector:
    connector.RunQuery(QUERY)

I thought it would be nice to be able to run single line commands like this

MySQLConnector().RunQuery(QUERY)

but this leaves the connection open.

I then thought this implementation would allow me to do single and multiple actions all nicely context managed.

class MySQLConnector():
    @staticmethod
    def RunQuery(query):
        with MySQLConnector() as connector:
            connector.RunQuery(query)

    def RunQuery(self, query):
        self.cursor.execute(query)
        self.connection.commit()

# Single Actions
MySQLConnector.RunQuery(QUERY)

# Mulitple Actions
with MySQLConnector() as connector:
    connector.RunQuery(QUERY_1)
    connector.RunQuery(QUERY_2)

However, the method function seems to override the static method and only one way will work at a time. I know I could just have two separately named functions but I was wondering if there was a better/more pythonic way to implement this?

Asked By: J Browne

||

Answers:

As this answer points out, you can use some __init__ trickery to redefine the method if it is being used as non-static (as __init__ will not run for static methods). Change the non-static RunQuery to something like _instance_RunQuery, then set self.RunQuery = self._instance_RunQuery. Like this:

class A:
    def __init__(self, val):
        self.add = self._instance_add
        self.val = val

    @staticmethod
    def add(a, b):
        obj = A(a)
        return obj.add(b)

    def _instance_add(self, b):
        return self.val + b


ten = A(10)
print(ten.add(5))

print(A.add(10, 5))
Answered By: Michael M.