Skip to content Skip to sidebar Skip to footer

How To Avoid Excessive Parameter Passing?

I am developing a medium size program in python spread across 5 modules. The program accepts command line arguments using OptionParser in the main module e.g. main.py. These option

Solution 1:

Create objects of types relevant to your program, and store the command line options relevant to each in them. Example:

import WidgetFrobnosticator
f = WidgetFrobnosticator()
f.allow_oncave_widgets = option_allow_concave_widgets
f.respect_weasel_pins = option_respect_weasel_pins

# Now the methods of WidgetFrobnosticator have access to your command-line parameters,# in a way that's not dependent on the input format.

import PlatypusFactory
p = PlatypusFactory()
p.allow_parthenogenesis = option_allow_parthenogenesis
p.max_population = option_max_population

# The platypus factory knows about its own options, but not those of the WidgetFrobnosticator# or vice versa.  This makes each class easier to read and implement.

Solution 2:

Maybe you should organize your code more into classes and objects? As I was writing this, Jimmy showed a class-instance based answer, so here is a pure class-based answer. This would be most useful if you only ever wanted a single behavior; if there is any chance at all you might want different defaults some of the time, you should use ordinary object-oriented programming in Python, i.e. pass around class instances with the property p set in the instance, not the class.

classAclass(object):
    p = None    @classmethoddefinit_p(cls, value):
        p = value
    @classmethoddefmeth1(cls):
        # some code
        res = cls.meth2()
        # some more code w/ res    @classmethoddefmeth2(cls):
        # do something with ppassfrom a import Aclassas ac

ac.init_p(some_command_line_argument_value)

ac.meth1()
ac.meth2()

Solution 3:

If "a" is a real object and not just a set of independent helper methods, you can create an "p" member variable in "a" and set it when you instantiate an "a" object. Then your main class will not need to pass "p" into meth1 and meth2 once "a" has been instantiated.

Solution 4:

[Caution: my answer isn't specific to python.]

I remember that Code Complete called this kind of parameter a "tramp parameter". Googling for "tramp parameter" doesn't return many results, however.

Some alternatives to tramp parameters might include:

  • Put the data in a global variable
  • Put the data in a static variable of a class (similar to global data)
  • Put the data in an instance variable of a class
  • Pseudo-global variable: hidden behind a singleton, or some dependency injection mechanism

Personally, I don't mind a tramp parameter as long as there's no more than one; i.e. your example is OK for me, but I wouldn't like ...

importap1=some_command_line_argument_valuep2=another_command_line_argument_valuep3= a_further_command_line_argument_value
a.meth1(p1, p2, p3)

... instead I'd prefer ...

importap= several_command_line_argument_values
a.meth1(p)

... because if meth2 decides that it wants more data than before, I'd prefer if it could extract this extra data from the original parameter which it's already being passed, so that I don't need to edit meth1.

Solution 5:

With objects, parameter lists should normally be very small, since most appropriate information is a property of the object itself. The standard way to handle this is to configure the object properties and then call the appropriate methods of that object. In this case set p as an attribute of a. Your meth2 should also complain if p is not set.

Post a Comment for "How To Avoid Excessive Parameter Passing?"