Search code examples
pythonpython-3.xconstructordefault-constructor

Why am I getting an error based on my parameterized constructor being called when I try to instantiate an object using my default constructor?


Any thoughts as to why I am unable to call the default constructor?

Here is a small part of the class so that you can see the available constructors and some of the data members:

class TweetExplorer:

    CLEAN_OUTPUT_PATH = constants.CLEAN_OUTPUT_PATH

    # Authorization keys
    API_KEY = ''
    API_SECRET_KEY = ''
    ACCESS_TOKEN = ''
    ACCESS_TOKEN_SECRET = ''

    OUTPUT_PATH = '' 

    API_ACCESS = 0

    def __init__(self):

        self.OUTPUT_PATH = constants.OUTPUT_PATH 
        self.CLEAN_OUTPUT_PATH = constants.OUTPUT_PATH


def __init__(self, api_key, api_secret_key, access_token, access_token_secret):

    self.API_KEY = api_key
    self.API_SECRET_KEY = api_secret_key
    self.ACCESS_TOKEN = access_token
    self.ACCESS_TOKEN_SECRET = access_token_secret

    try: 
        self.check_access()
    except Exception as ex:
        print(ex)

    self.OUTPUT_PATH = constants.OUTPUT_PATH 

So, in the same file, I attempt to instantiate an instance of the class by using the default constructor:

if __name__ == '__main__':

    explorer = TweetExplorer()

Instead of calling the default constructor, I get the following error:

Message=init() missing 4 required positional arguments: 'api_key', 'api_secret_key', 'access_token', and 'access_token_secret' Source=C:\source\repos\TweetExplorer\TweetExplorer.py StackTrace: File "C:\source\repos\TweetExplorer\TweetExplorer.py", line 499, in explorer = TweetExplorer()


Solution

  • A pattern I have used before for providing multiple constructors is to use classmethods:

    class TweetExplorer:
    
        CLEAN_OUTPUT_PATH = constants.CLEAN_OUTPUT_PATH
        API_ACCESS = 0
    
        def __init__(self):
            self.OUTPUT_PATH = constants.OUTPUT_PATH
            self.CLEAN_OUTPUT_PATH = constants.OUTPUT_PATH
            self.API_KEY = ''
            self.API_SECRET_KEY = ''
            self.ACCESS_TOKEN = ''
            self.ACCESS_TOKEN_SECRET = ''
    
        @classmethod
        def with_credentials(cls, api_key, api_secret_key, access_token, access_token_secret):
            obj = cls()
    
            obj.API_KEY = api_key
            obj.API_SECRET_KEY = api_secret_key
            obj.ACCESS_TOKEN = access_token
            obj.ACCESS_TOKEN_SECRET = access_token_secret
    
            try:
                obj.check_access()
            except Exception as ex:
                print(ex)
    
            return obj
    

    Now you can initialise TweetExplorer without any arguments

    TweetExplorer()
    

    Or with the creds

    TweetExplorer.with_credentials(api_key, api_secret_key, access_token, access_token_secret)