Raheel
Raheel

Reputation: 9024

Python way of managing dependencies

So In PHP, We normally pass our dependencies through constructor.

like

<?php

class Downloader
{
    public function __construct(LoggerInterface $logger){}

}

But in Python (I am beginner), I see we can use objects defined outside of class scope can be used directly.

logger = logging.getLogger('mylogger')

class Downloader():
    def download():
        logger.alert('I am downloading..')

I want to understand the recommendations of how python developers use services inside class.

Upvotes: 1

Views: 91

Answers (3)

hspandher
hspandher

Reputation: 16733

Well, it depends. If there is something that is not going to be mutated and is common for all the classes in a file or module, then I tend to use it directly without passing it through the constructor, or otherwise, I define a variable at the class level, if I want to modify it in inherited classes.

In your case, if the downloader class (and all those who inherit from it) are always going to use the one and same logger, then I see no problem in using it the way you're doing right now.

# Case 1
# In case you want to allow logger being different for inherited classes.

class BaseDownloader(object):

      logger = Logger1

class Downloader1(BaseDownloader):

      logger = Logger2

# Case 2
# In case you want different logger for every instance

class Downloader(object):

      def __init__(self, logger):
           self.logger = logger

# Case 3
# If you don't need that kind of customizability, then using it directly
# is perfectly fine. In fact, that's how I'd start with, and change it
# later if the need arises.

class Downloader(object):

      def download():
          logger.alert('I am downloading')

Upvotes: 1

Yardid
Yardid

Reputation: 232

In my case, I like to only instance dependencies in the class itself

class Downloader():
    logger = logging.getLogger('mylogger')
    def download():
        logger.alert('I am downloading..')

Another option would be to pass the dependency as an argument at class creation

logger = logging.getLogger('mylogger')

class Downloader():
    def __init__(self, logger):
        self.logger = logger
    def download():
        logger.alert('I am downloading..')

downloader = Download(logger)

Upvotes: 1

Cory Kramer
Cory Kramer

Reputation: 117866

I wouldn't depend on it being in global scope, I'd either make it a class level member

class Downloader():
    logger = logging.getLogger('mylogger')

    def download(self):
        logger.alert('I am downloading..')

or instance level member

class Downloader():
    def __init__(self):
        self.logger = logging.getLogger('mylogger')

    def download(self):
        self.logger.alert('I am downloading..')

Upvotes: 1

Related Questions