foobarbecue
foobarbecue

Reputation: 7070

pass a python module to a function

Does it ever make sense to pass a module as an argument into a function in python?

My python-sense says this idea is wrong but I'm not sure exactly why.

Here's where I encountered it. I'm using Django's messaging framework, django.contrib.messages . I am also using a parsing module that I wrote for other purposes and importing a class from it into my django application. Then I realized I want to set messages during parsing.

The parsing module does not depend on Django at all, and I'd rather not import django in the parsing module, because that would introduce a dependency.

I imagine the correct answer here is to add a conditional import of django into the parsing module.

But then I thought: why can't I just have the class I'm using in the parsing module accept the messaging module as an optional argument?

Upvotes: 4

Views: 5074

Answers (1)

tdelaney
tdelaney

Reputation: 77407

I think it's a reasonable solution. Your parser isn't just importing django.contrib.messages, it's deciding on an entire API to use for messaging. By passing in the module, you are really passing in the entire API. You'll have a bunch of if statements that conditionally do messaging based on some sort of a configuration parameter. That parameter could be the djang.contrib.messages module itself or some flag that says to do messaging. I prefer the latter because its a bit awkward to have the caller import the module.

class Parser(object):

    def __init__(self, use_messaging=False):
        if use_messaging:
            try:
                self.messages = __import__('django.contrib.messages') 
            except ImportError:
                print "dude, you really need to read the help secton"
                sys.exit(1)
        else:
            self.messages = None

    def parse(self):
        if self.messages:
            self.messages.send_message("I am parsing now")

You could get fancier with a config file so that messaging is optionally enabled not by the caller but by configuration of the application itself. That makes sense because somewhere along the line you have to configure who to send messages to. But the basic concept is fine.

@DaniaelRoseman has a valid concern about dependency injection, but I think its only a concern at installation (you could write different pip requirement rules for different products for instance) and should be easy to work around.

Upvotes: 2

Related Questions