Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Overload Python 'in' to return non-bool

I'm trying to overload the in operator for a class to return a non-bool object, but it seems to cast anyway. Here is my use case:

class Dataset(object):
  def __init__(self):
    self._filters = []

  def filter(self, f):
    self._filters.append(f)
    return self

class EqualFilter(object):
  def __init__(self, field, val):
    ...

class SubsetFilter(object):
  def __init__(self, field, vals):
    ...

class FilterBuilder(object):
  def __init__(self, field):
    self._field = field

  def __eq__(self, val):
    return EqualFilter(self._field, val)

  def __contains__(self, vals):
    return SubsetFilter(self._field, vals)


veggie = FilterBuilder('veggie')
fruit = FilterBuilder('fruit')
ds = Dataset().filter(veggie == 'carrot').filter(fruit in ['apple', 'orange'])

At the end of the code, ds contains an EqualFilter for veggie == 'carrot', and True for fruit in ['apple', 'orange']. Is there any way for ds to end up with a SubsetFilter?

like image 383
user108088 Avatar asked Jan 12 '23 09:01

user108088


1 Answers

There are two problems here. First, in always casts the result of __contains__ to a bool, so what you're looking for isn't possible. The second problem is that

fruit in ['apple', 'orange']

calls

['apple', 'orange'].__contains__(fruit)

There's no way for the left operand of in to override the operator, so that's also going to defeat what you're trying to do.

like image 60
user2357112 supports Monica Avatar answered Jan 22 '23 17:01

user2357112 supports Monica