Search code examples
pythonstatic-methodsinstance-method

Python when to use instance vs static methods


I am struggling to understand when it makes sense to use an instance method versus a static method. Also, I don't know if my functions are static since there is not a @staticmethod decorator. Would I be able to access the class functions when I make a call to one of the methods?

I am working on a webscraper that sends information to a database. It’s setup to run once a week. The structure of my code looks like this

import libraries...
class Get:
    def build_url(url_paramater1, url_parameter2, request_date):
        return url_with_parameters

    def web_data(request_date, url_parameter1, url_parameter2): #no use of self
        # using parameters pull the variables to look up in the database
        for a in db_info:
            url = build_url(a, url_parameter2, request_date)
            x = requests.Session().get(url, proxies).json()
            #save data to the database
        return None

    #same type of function for pulling the web data from the database and parsing it

if __name__ == ‘__main__’:
    Get.web_data(request_date, url_parameter1, url_parameter2)
    Parse.web_data(get_date, parameter) #to illustrate the second part of the scrapper

That is the basic structure. The code is functional but I don’t know if I am using the methods (functions?) correctly and potentially missing out on ways to use my code in the future. I may even be writing bad code that will cause errors down the line that are impossibly hard to debug only because I didn’t follow best practices.

After reading about when class and instance methods are used. I cannot see why I would use them. If I want the url built or the data pulled from the website I call the build_url or get_web_data function. I don’t need an instance of the function to keep track of anything separate. I cannot imagine when I would need to keep something separate either which I think is part of the problem.

The reason I think my question is different than the previous questions is: the conceptual examples to explain the differences don't seem to help me when I am sitting down and writing code. I have not run into real world problems that are solved with the different methods that show when I should even use an instance method, yet instance methods seem to be mandatory when looking at conceptual examples of code.

Thank you!


Solution

  • The functions you have wrote in your code are instance methods but they were written incorrectly. An instance method must have self as first parameter

    i.e def build_url(self, url_paramater1, url_parameter2, request_date):

    Then you call it like that

    get_inst = Get()
    get_inst.build_url(url_paramater1, url_parameter2, request_date)
    

    This self parameter is provided by python and it allow you to access all properties and functions - static or not - of your Get class.

    If you don't need to access other functions or properties in your class then you add @staticmethod decorator and remove self parameter

    @staticmethod
    def build_url(url_paramater1, url_parameter2, request_date):
    

    And then you can call it directly

    Get.build_url(url_paramater1, url_parameter2, request_date)
    

    or call from from class instance

    get_inst = Get()
    get_inst.build_url(url_paramater1, url_parameter2, request_date)
    

    But what is the problem with your current code you might ask? Try calling it from an instance like this and u will see the problem

    get_inst = Get()
    get_inst.build_url(url_paramater1, url_parameter2, request_date)
    

    Example where creating an instance is useful: Let's say you want to make a chat client.

    You could write code like this

    class Chat:
        def send(server_url, message):
            connection = connect(server_url)
            connection.write(message)
            connection.close()
    
        def read(server_url):
            connection = connect(server_url)
            message = connection.read()
            connection.close()
            return message
    

    But a much cleaner and better way to do it:

    class Chat:
    
        def __init__(server_url):
            # Initialize connection only once when instance is created
            self.connection = connect(server_url)
    
        def __del__()
            # Close connection only once when instance is deleted
            self.connection.close()
    
        def send(self, message):
            self.connection.write(message)
    
        def read(self):
            return self.connection.read()
    

    To use that last class you do

    # Create new instance and pass server_url as argument
    chat = Chat("http://example.com/chat")
    chat.send("Hello")
    chat.read()
    # deleting chat causes __del__ function to be called and connection be closed
    delete chat