For instance, these are defined in the operator module and can be used as such:
import operator
print operator.__add__ # alias add -> +
print operator.__sub__ # alias sub -> -
print operator.__and__ # alias and_ -> &
print operator.__or__ # alias or_ -> |
Then what is the equivalent of and
and or
?
print operator."and ?????" # should be boolean-and
print operator."or ????" # should be boolean-or
The and
and or
operators don't have an equivalent in the operator module, because they can't be implemented as a function. This is because they are short-circuiting: they may not evaluate their second operand depending on the outcome of the first.
These do not exist. The best you can do is to replace them with a lambda:
band = (lambda x,y: x and y)
bor = (lambda x,y: x or y)
The reason is you can not implement the complete behavior of and
or or
because they can short circuit.
E.G:
if variable or long_fonction_to_execute():
# do stuff
If variable
is True
, the long_fonction_to_execute
will never be called because Python knows than or
has to return True
anyway. It's an optimization. It's a very desirable feature most of the time, as it can save a lot of useless processing.
But it means you cannot make it a function:
E.G:
if bor(variable, long_fonction_to_execute()):
# do stuff
In that case, long_fonction_to_execute
is called even before being evaluated.
Luckily, you rarely need something like that given the fact that you an use generators and list comprehensions.
Extension of e-satis's answer:
lazyand = (lambda x,y: x() and y())
lazyor = (lambda x,y: x() or y())
The difference here is the conditions passed in are themselves thunks (functions of the form "() -> value") which are only evaluated as needed. (It could be argued that only y
needs to be lazily evaluated, but I wrote it as such for consistency).
That is, this preserves the "lazy" aspect of and
(and or
) at the expense of more verbose code and more objects/method invocations.
andexpr = lazyand(lambda: false, lambda: never_executed())
andexpr() # false
I would be hard pressed to actually recommend using this approach though - it is important to note that these thunks must be explicit, as shown above. This might be one reason it was not included in the operator
module. Some other languages allow pass-by-name or implicit "lifting".
Happy coding.
精彩评论