4

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?

asked Sep 27, 2013 at 15:38
5
  • You're talking about dependency injection, which is a difficult subject in Python. Commented Sep 27, 2013 at 15:42
  • It's rare to have two modules with the same interface, so this wouldn't often make sense. Since you're locked to the interface you might as well lock to the specific module as well. Commented Sep 27, 2013 at 16:56
  • @MarkRansom, I think I see what you're saying, but I'm also using the same parsing module in a desktop application that doesn't need django, and I'm expecting others will want to use the parsing module in future apps. This would be an example of "two modules with the same interface", right? Commented Sep 27, 2013 at 17:24
  • Maybe I'm misreading the question. Is what you're passing a choice between two different modules, or between a single module and None? Commented Sep 27, 2013 at 18:01
  • Between a single module and None. Commented Sep 27, 2013 at 18:16

1 Answer 1

2

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.

answered Sep 27, 2013 at 16:47
Sign up to request clarification or add additional context in comments.

3 Comments

I wanted to fix your "its" but it won't let you edit to insert 2 apostrophes! Nice to know I'm not sinning against python if I do it my way. The use_messaging flag method does look better.
@foobarbecue - I get my contractions and possessives mixed up all the time.
Heheh, that's unfortunate. As for me, I'm perfect and never make any mistakes. You missed one: "I think its only a concern"

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.