4

Following the first example of this answer, I split the implementation of my class in different modules, similar to

class MyClass:
    from impl0 import foo00, foo01
    from impl1 import foo10, foo11

I would now like to import one or the other of two different implementations of some methods based on a parameter that becomes known only at instantiation time, e.g.,

class MyClass:
    from impl0 import foo00, foo01

    def __init__(self, par):
        if par:
            from impl1 import foo10, foo11
        else:
            from alternative_impl1 ipmort foo10, foo11

However, doing like in the previous snippet restricts the visibility of foo10 and foo11 to the __init__ function only. Is there a way to achieve this class-wise?

japs
  • 1,286
  • 13
  • 27
  • Where does `par` come from? Who is setting it? –  Apr 09 '18 at 12:34
  • I think, may be OP want us to assume that MyClass as MyClass(arg) – Raja G Apr 09 '18 at 12:35
  • @LutzHorn: I mean that the class is initialised with a parameter somewhere else, where the MyClass is used. For your curiosity, par are many physical parameters in a physics simulation. The user passes them from command line, and the program then instantiates the class passing several arguments to the constructor. – japs Apr 09 '18 at 13:48

1 Answers1

3

Assign the module to an instance (or class) variable:

if par: 
   from impl1 import foo10, foo11
else:
   from impl2 import foo10, foo11
self.foo10 = foo10
self.foo11 = foo11
Guybrush
  • 2,680
  • 1
  • 10
  • 17
  • unfortunately when you do that, those functions stop working as well behaved class methods, i.e., you can't call them as self.foo10(parameters) but you have to use something like self.foo10(self, parameters), which I would like to avoid. – japs Apr 09 '18 at 13:40
  • What do you want to do exactly? Conditional import seems to be only part of it. –  Apr 09 '18 at 13:50
  • 1
    You can use the `staticmethod` decorator to make them callable using `self.foo10(parameter)`. If these "methods" are expected to make use of "self" as first parameter, they have to be converted from unbound functions to bound methods. A naive way to do that is to change how they are assigned to the current scope, ie, replacing `self.foo10 = foo10` by something like `self.foo10 = partial(foo10, self)` using `partial` from `functools` module. – Guybrush Apr 09 '18 at 14:12
  • @LutzHorn: I want to do conditional import and nothing more, hence not having to change all the calls to those class methods. – japs Apr 09 '18 at 14:19
  • @Guybrush: The use of staticmethod raises errors. However, your hint to use functools.partial was decisive. – japs Apr 09 '18 at 15:11
  • Staticmethod shouldn't be used as a decorator but call eg: self.foo10 = staticmethod(foo10) I think. Glad to see that partial fits your need. Don't forget to upvote the answer and the comment so it could help other people too. – Guybrush Apr 09 '18 at 15:15