1

I'm working on a python class that is being shared between two products. 90% of the functionality applies to both products. For the 10% that's different the code is littered with this kind of thing:

#Start of file
project = 'B'
#Some line of code
if project == 'A':
 import moduleA
elif project == 'B':
 import moduleB
#Many lines of code
if project == 'A':
 print moduleA.doA(2)
elif project == 'B':
 print moduleB.doB(2)

This doesn't seem very elegant or very readable, has anyone encountered this sort of thing before? Are there better ways of doing it?

asked May 12, 2010 at 23:20
2
  • I suspect your package that is shared between the two projects isn't designed to be modular enough. Can you provide us with more examples where your code is shared? Refactor may be key. Commented May 12, 2010 at 23:25
  • Who is who?. Where the class is?. Can you elaborate more precisely the question/example? Commented May 12, 2010 at 23:32

3 Answers 3

3

No, as this is very poor design. If your module's behavior is influenced by the project in which it is used, then it should accept an object, function, or other callback for the project-specific behavior. My suggestion is to factor out the pieces that are shared and make them into a single module, and for anything that is project-specific, add a dependency on an object that needs to be passed in, and require that the object conform to some interface. Then, wrap your project-specific behaviors in an object that conforms to the required interface and pass it to the common, shared module.

answered May 12, 2010 at 23:30
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the advice, I'm going to give this a go.
0

Your shared module should implement a base class with the functionality common to both using modules, then each using module will subclass that base class and add or tweak what's necessary. There are other good approaches (such as the suggestion in @Michael's answer, which is known as the Dependency Injection design patterns), but usually subclassing and overriding is the simplest way to "customize" functionality for different specific needs (it does lead to high and rigid coupling, but that's often quite acceptable as the cost of simplicity).

answered May 13, 2010 at 1:30

Comments

0

Another possible approach, if neither of the two answers given so far are practical, is to define the interface at the import level. For instance:

if project == 'A':
 from moduleA import doA as doproject
elif project == 'B':
 from moduleB import doB as doproject
# many lines of code
doproject(2)

This concept (although not this specific problem) is one of the things that "import X as Y" is really good for.

You could also get cleverer with constructing imports based on the project name, making a dictionary keyed by project that had as its value the module to call, and that sort of thing. But I wouldn't go that direction unless I was really sure that refactoring so I could pass in the modules I need wouldn't work.

answered May 13, 2010 at 4:21

Comments

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.