重载Python';在';返回非bool
我试图为类重载重载Python';在';返回非bool,python,operator-overloading,Python,Operator Overloading,我试图为类重载in操作符以返回非bool对象,但它似乎还是强制转换。以下是我的用例: 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): ...
in
操作符以返回非bool对象,但它似乎还是强制转换。以下是我的用例:
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'])
在代码末尾,
ds
包含一个EqualFilter
用于vegige==“carrot”
,以及True
用于苹果、橘子中的水果。有没有办法让DS以“<代码>子设置过滤器< /代码>?< /p> <代码> >列表。首先,
中的总是将\uuuuuuuuuuuuuuuuuuuuuu包含的结果强制转换为bool
,因此您所查找的内容是不可能的。第二个问题是
fruit in ['apple', 'orange']
召唤
在
中,的左操作数无法重写运算符,因此这也将挫败您的尝试。这里真正的问题是,如所述:
对于定义\uuuu contains\uuuu()方法的用户定义类,y中的x
当且仅当y时为真
另请参见和
user2357112的回答比我能更好地解释这一点。您正在调用的是list.\uuu包含\uuu
,而不是FilterBuilder.\uu包含\uuu
但为什么会这样呢
好吧,不然怎么行呢
假设[1,2,3]
中的3被称为int.\uu包含\uuu
。在{1,2,3}
中的3以及在我的自定义排序的bintree中的3也是如此。如何实现int.\uuuuuuuuuuuuuuuuuuuuuuu(容器)
?当然不是通过在容器上迭代。这将意味着在集合和二叉树中缓慢、彻底地查找内容,这将破坏整个要点。我的bintree类甚至可能不可移植,但可能仍然有成员的概念
但是如果他们调用list.\uuuu包含\uuuu
,set.\uuu包含\uuuu
和CustomSortedBintree.\uu包含\uuu
?他们不需要知道int和str,以及你能给他们的所有其他可能的东西吗?不,一点也不。列表只需知道如何比较每个元素的arg==elem
。集合还需要知道如何调用哈希(arg)
。bintree还必须知道如何调用arg
。但要做到这一点,您不需要知道任何关于arg的类型
你可能想知道如何处理这件事。有两种半通用的解决方案
1:您可以轻松创建过滤器列表
类。然后,你只要写:
fruit in FilterList('apple', 'orange')
1.5:或者,再多做一点工作,您可以构建一个更通用的“价值持有者”:
2:或者,您可以在
方法中编写一个FilterBuilder.in。然后你写:
fruit.in_(['apple', 'orange'])
…或者,如果您愿意:
fruit.in_('apple', 'orange')
我见过的大多数库要么提供第二个(sqlalchemy),要么同时提供这两个库,但在它们的教程(appscript)中使用第二个库,尽管“quick lambda”库通常使用第一个库的通用版本
<>但是你应该考虑你自己的用例的权衡。一般来说,第一种方法更容易实现,而且更明确,其优点是子过滤器/子查询可以返回充当过滤器列表的内容
;第二种方法不那么冗长,而且可以说更容易阅读
如果没有一个是可接受的,您可以考虑编写一个Python类DSL的解析器,而不是试图通过表达式模板从实际Python代码中构建DSL。或者使用类似的方法(我认为它甚至有一个与您正在寻找的类似的示例,以及不需要“const”和friends的quick lambda宏)。
向FilterBuilder添加一个print语句。\uuu包含\uuuuuuuuu确实会导致打印,所以我相当确定FilterBuilder.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu@user1088:来自FilterBuilder的一些代码路径。\uuuuuuuuuuuuuuuuuuuuuuuuuu。当我实现一个类打印机(对象)
时,它的\uuuuuuuuuuuuuuuuuuuuuuuuuuuu方法中有一个print
,4 in Printer()
打印,但是[1,2,3]
中的打印机()不打印。@abarnet:error reply target?@user2357112:对不起,是的。顺便说一句,从我所知,不能保证
中的会将结果强制转换为bool
。所有相关文档都只是说,如果\uuuuu包含\uuuuu
返回一个真值,那么它将是一个真值。它可以通过返回bool来实现,但也可以返回值本身。正如您所期望的那样,返回bool,至少Jython和PyPy也是如此,但我仍然认为它取决于实现。@sharth:谢谢您的修复。
fruit.in_(['apple', 'orange'])
fruit.in_('apple', 'orange')