2

I have a program that runs on two platforms. Each platform has a different set of imported modules. Many of the def statements on one platform need an additional parameter to run with its set of imports. Not every def statement needs to be changed.

If something like this worked, it would be make things easier:

if platform_1:
   def func(this, that):
else:
   def func(self, this, that):

   func_body

Is there any way do do this?

foosion
  • 7,619
  • 25
  • 65
  • 102
  • 3
    Have you looked at http://stackoverflow.com/questions/560040/conditional-compilation-in-python? – Ray Toal Sep 09 '11 at 00:22
  • @Ray, I hadn't but it doesn't really help. I could do if X: def func(); body; else: def func(this); body. That would require repeating the body twice, unless I'm missing something from that thread. – foosion Sep 09 '11 at 00:29
  • Please explain what you're **really** trying to do. What is the additional parameter? Why isn't it needed on the other platform? – Karl Knechtel Sep 09 '11 at 04:03
  • @Karl, running on pc with tkinter and phone with its GUI. Example of issue, on pc button callback is cbk_func(self, event=None) and on phone it's cbk_func(self). Body of cbk_func is the same. – foosion Sep 09 '11 at 10:58
  • ... Either the thing that calls your callback will pass you an event, or it won't. If it does, then the phone version must accept it, if only to ignore it. If it doesn't, then the default argument to the PC version is useless, since `event` isn't used in the body of the function, since you said it's the same on both platforms and using `event` when it **isn't** passed would raise an exception somewhere. – Karl Knechtel Sep 09 '11 at 21:56

3 Answers3

3

I wonder why a function should have an argument that it never uses. Wouldn't it be better to fix the surrounding code that forces you into this situation?

Nevertheless, it is possible...

def narcissist(func):
    def wrapper(self,*args,**kwargs):
        return func(*args,**kwargs)
    return wrapper

def identity(func):
    return func

if platform_1:
    modify_args=identity
else:
    modify_args=narcissist

@modify_args
def func(this,that):
    func_body
unutbu
  • 842,883
  • 184
  • 1,785
  • 1,677
  • The reason the function has an argument it never uses is due to the construction of the modules that must be imported, not the calling function. – foosion Sep 09 '11 at 00:38
2

If the imports aren't actually calling your func, you're making things harder for yourself, and you want to do:

def func( self, this, that ):
    if platform_1:
        # do something with just this and that, ignoring self
        import_1.doSomething( this, that )
    else:
        # do something with self, this, that
        import_2.doSomething( self, this, that )

If the platform-specific code is calling into your func, I'd consider defining one version of func as a wrapper for the other, with two separate names.

Russell Borogove
  • 18,516
  • 4
  • 43
  • 50
2

i think you could do this with a decorator, if the change was always of the same form. for example, the following would add a first argument of None if the system is X:

def multiplatform(function):
    if system is X:
        def wrapper(*args, **kargs):
            return function(None, *args, **kargs)
    else:
        def wrapper(*args, **kargs):
            return function(*args, **kargs)
    return wrapper

@multiplatform
def foo(first, second, third):
    '''first should not be given on platform X'''
    print(first, second, third)

and then on system X:

>>> foo(2, 3)
None 2 3

while on other systems

>>> foo(1, 2, 3)
1 2 3

disclaimer: untested code, but should give the general idea.

andrew cooke
  • 45,717
  • 10
  • 93
  • 143