0

The following code in file script.py makes it possible (after chmod 755 script.py) to either script.py dothis or to script.py dothat.

import sys

class DoThisOrThat:
    @staticmethod
    def dothis():
        print "We're doing this."

    @staticmethod
    def dothat():
        print "We're doing that."

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print "Error: You must specify exactly one function: dothis or dothat"
        sys.exit(1)
    if sys.argv[1] == "dothis":
        FooBar.dothis()
    elif sys.argv[1] == "dothat":
        FooBar.dothat()
    else:
        print "I don't know how to "+sys.argv[1]

Is this the most elegant way to call one of two static member methods from the command line?

Solutions using either argparse or argh are possible if the methods are nonmember. What is the equivalent for the code above?

Community
  • 1
  • 1
Calaf
  • 10,113
  • 15
  • 57
  • 120

3 Answers3

1

You can use the getattr builtin to call any methods (static / instance / class) of a class (or of an instance)

Assuming your Factory class is

>>> class DoThisOrThat:
    @staticmethod
    def dothis_static():
        print "We're doing this static."

    @staticmethod
    def dothat():
        print "We're doing that static."
    def dothis_instance(self):
        print "We're doing this instance."
    @classmethod
    def dothis_classmethod(cls):
        print "We're doing this class method."

Then a possible invocation would be

>>> getattr(DoThisOrThat, 'dothis')()
We're doing this.
>>> getattr(DoThisOrThat(), 'dothis_instance')()
We're doing this instance.
>>> getattr(DoThisOrThat, 'dothis_classmethod')()
We're doing this class method.

This modifies your code as

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print "Error: You must specify exactly one function: dothis or dothat"
        sys.exit(1)

    try:
        getattr(DoThisOrThat, sys.argv[1])()
    except AttributeError:
        print "I don't know how to " + sys.argv[1]
Abhijit
  • 62,056
  • 18
  • 131
  • 204
0

If you want to allow calling arbitrary staticmethods of a class from the commandline, you can also use getattr to accomplish this, assuming of course the argument and method names match 1-to-1:

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print("Error: You must specify exactly one function")
        sys.exit(1)
    try:
        getattr(DoThisOrThat, sys.argv[1])()
    except AttributeError:
        print("Error: The specified method '%s' does not exist" % sys.argv[1])
        sys.exit(1)
lemonhead
  • 5,328
  • 1
  • 13
  • 25
0

You can define a dictionary to map the strings to the functions.

>>> d = {'dothis': DoThisOrThat.dothis, 'dothat': DoThisOrThat.dothat}
>>> d['dothis']()
We're doing this.
>>> d['dothat']()
We're doing that.

if __name__ == "__main__":
    if len(sys.argv) != 2:
        print "Error: You must specify exactly one function: dothis or dothat"
        sys.exit(1)
    try:
        d[sys.argv[1]]()
    except KeyError:
        print "I don't know how to "+sys.argv[1]
Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Might it be possible to do something like this: http://stackoverflow.com/a/33660814/704972 by writing f = MyObject...[args.thing]? What would the "..." be? – Calaf Nov 13 '15 at 04:57