Home > Enterprise >  Calling __init__ for super() with conditional arguments
Calling __init__ for super() with conditional arguments

Time:07-20

What would be the pythonic way to achieve the following usecase:

  • Import a module conditionally
  • Inherit from that module
  • Call super.__init__() with parameters based on which module we inherited from

Eg. I am trying to have my app compatible with both cmd and cmd2 module. Since cmd2 supports history, I need to call its init with additional parameters. But it's ok if user doesn't have that module installed

I am handling it this way. Though it works, I don't like the solution myself

try:
    import cmd2 as CMD
except:
    import cmd as CMD

class MyApp(CMD.Cmd):
    def __init__(self):
        if globals()['CMD'].__name__ == "cmd2":
            super().__init__(persistent_history_file="~/myapp_history.dat", allow_cli_args=False)
        else:
            super().__init__()

Note: This question is not specific to cmd/cmd2 module. That is just an example

I am trying to find the best way to achieve this for any such usecase

CodePudding user response:

One approach would be to create an intermediate class based on the imported module in the try-except block, override the __init__ method accordingly in the intermediate class, so that your main class can inherit from it cleanly:

try:
    import cmd2
    class CMD(cmd2.Cmd):
        def __init__(self):
            super().__init__(persistent_history_file="~/myapp_history.dat", allow_cli_args=False)
except:
    import cmd
    class CMD(cmd.Cmd):
        def __init__(self):
            super().__init__()

class MyApp(CMD):
    # define other attributes and methods here
    pass

CodePudding user response:

Usually, you try to import different modules if they have completely same functionality and one had faster speed.

e.g.

try:
    import json5 as json
except ImportError:
    import json
# Pasted from the requests library

In your case, if there's only one difference look at @blhsing's answer. It is a perfect approach without writing too much code.

Otherwise I recommend the following:

use_cmd2 = True
try:
    import cmd2 as CMD
except:
    import cmd as CMD
    use_cmd2 = False

class MyApp(CMD.Cmd):
    def __init__(self):
        if use_cmd2:
            super().__init__(persistent_history_file="~/myapp_history.dat", allow_cli_args=False)
        else:
            super().__init__()

    def foo(self):
        if use_cmd2:
            pass # special
        else:
            pass # ordinary
  • Related