1

In languages that use static binding like java you can define multiple functions all having the same name but different parameters. Learning Python, until now I considered the lack of this mainly as "safety issue" (like bool_parameter="False" might be interpreted as True because of the quotes). I thought I would simply need to be more careful.

Now I found a situation, where the lack of static binding is simply inconvenient. Please consider this tupel:

var = ((1, "foo"), (2, "bar"), (3, "potato"))

To remove an item from var with static binding one could do something like this(pseudocode:

def del_item(int i):
    # search item with (x == i, *)
    # remove this item

def del_item(String s):
    # search item with (*, x == s)
    # remove this item

I find this very convenient, because no conditions are needed to select the right action to perform. Furthermore this code makes overloading easier, as one can decide to just overload one of the functions or both.

Trying to deal with a situation like this in Python, I only find inconvenient solutions like some if-clauses that check for the type.

Is there a better way?

speendo
  • 13,045
  • 22
  • 71
  • 107
  • 1
    you could always have the delete operation on a class instead, so you just ask it to delete and it's internals take care of what specific delete is done. – Paul Collingwood Nov 23 '14 at 13:31
  • these are two distinct deletes. The first looks for the first element the second for the second argument. Normally this to deletes occur in totally different situations,so a del_on_first_element and del_on_second_element method is much clearer than type-overloading. – Daniel Nov 23 '14 at 13:39

4 Answers4

2

Python doesn't have overloading of methods so you're going to have to check the type of the argument sorry.

def del_item(item):
    if type(item) is int:
        # search item with (x == item, *)
        # remove this item
    elif type(item) is str:
        # search item with (*, x == s)
        # remove this item
    else:
        # Maybe raise an exception?
DanielGibbs
  • 9,910
  • 11
  • 76
  • 121
  • I like this answer as it points out, that my assumption (it is originally not intended) is in fact the case. However, @deets shows a workaround, which is also nice. I will think a little more which of these answer I should rather accept... – speendo Nov 23 '14 at 22:57
1

check out this question: Differences between isinstance() and type() in python

If you end up doing the if type approach suggested, you may want to consider duck typing or isinstance alternatives

Community
  • 1
  • 1
user3684792
  • 2,542
  • 2
  • 18
  • 23
1

Your problem could be tackled by using generic methods/functions. These don't come built-in with python, but can be roped in by either a 3rd-party library, or you write one yourself.

I have been working happily with PEAK rules a few years ago, but while it should still work, it seems to have fallen out of favour a bit.

The new PEP 443 (single argument dispatch) is accompanied by external implementation, singledispatch. https://pypi.python.org/pypi/singledispatch/3.4.0.3

With that, your problem could be solved like this:

 from functools import partial
 from singledispatch import singledispatch


 var = ((1, "foo"), (2, "bar"), (3, "potato"))


 @singledispatch
 def del_predicate(value):
     pass


 @del_predicate.register(int)
 def _(v, candidate):
     return v == candidate[0]

 @del_predicate.register(str)
 def _(v, candidate):
     return v == candidate[1]


 def neg(f):
     def _f(*args):
         return not f(*args)
     return _f

 print filter(neg(partial(del_predicate, "foo")), var)
 print filter(neg(partial(del_predicate, 2)), var)
deets
  • 6,285
  • 29
  • 28
  • So in principle, there is problem is not really to be easily addressed in Python. However, you provide a nice workaround. I like your answer and @DanielGibbs answer as well. I will think a little more which answer I should rather accept. – speendo Nov 23 '14 at 22:59
  • 1
    I would make the decision dependent on how frequent an issue like that occurs so it justifies introducing a new idiomatic way to solve it. Code is read more often than it's written - and Daniel's answer can be understood with no further knowledge type-based dispatch. Make that your judge on this. – deets Nov 23 '14 at 23:37
  • I also heard rumors some kind of optional static typing will be introduced in python3. However, I didn't find a real evidence about that. – speendo Nov 23 '14 at 23:58
  • 1
    These rumors are wrong - what exists is an (optional) type annotation system: https://docs.python.org/3/tutorial/controlflow.html#function-annotations An optimizing compiler could use this, and a generic function mechanism as well - but I'm not aware of either being actually used. – deets Nov 24 '14 at 13:14
0

The particular case you give seems like one where overloading is not needed anyway.

def del_item(id):
    return tuple(item for item in var if not id in item)

Another option is to use optional keyword arguments

def del_item(string_id=None, number_id=None):
    if string_id is not None:
        return tuple(item for item in var if not item[1] == string_id)
    return tuple(item for item in var if not item[0] == number_id)

There are lots of previous questions on python overloading, and this is one answer that might help understand why it's not seen as a problem not to have it.

Community
  • 1
  • 1
Stuart
  • 9,597
  • 1
  • 21
  • 30