# Proposed additions to \`operator\`

**URL:** <https://discuss.python.org/t/proposed-additions-to-operator/49846>\
**Category:** Ideas\
**Created:** [March 29, 2024, 5:07pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846 "2024-03-29T17:07:59Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [March 29, 2024, 5:07pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/1 "2024-03-29T17:07:59Z")

</div>

a) There are `operator.is_` and `operator.is_in`. I propose also adding:

```python
def in_(a, b):
    return a in b

def not_in(a, b):
    return a not in b

```

b) There are `operator.call` and it’s object `operator.caller`. There is `operator.methodcaller`. I propose adding:

```python
def callmethod(obj, name, /, *args, **kwds):
    return getattr(obj, name)(*args, **kwds)

```

c) To complete functionals I also propose adding:

```python
def map_(obj, func, /, *args, **kwds):
    return func(obj, *args, **kwds)

class mapper:
   ...

```

d) And finally, not sure if this could be a place for it, but I found it useful. To add to dictionary operations. Common operation, but not operator:

```python
def get(obj, idx, default=None):
    try:
        return obj[idx]
    except (KeyError, IndexError):
        return default

```

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [March 29, 2024, 5:37pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/2 "2024-03-29T17:37:10Z")

</div>

a) You are aware of `operator.contains`, right? The reverse operation better mirrors the data model of python (the ` __contains__ ` method), which is one of the reasons for this entire module to exists in the first place. Why is it necessary, or even all that helpful, to add `in_` and `not_in`?

b) `operator.caller` doesn’t exists. What are the potential use-cases for `callmethod` you are seeing? it seems quite hard to use with regard to use with `map` or a similar interface in contrast to other available functions

c) Having `map` and `map_` both existing is IMO a non-starter. I am not really sure what your goal with this operation is, but it should have a different name. This seems to just be an alias for `call` with a slightly different (and more confusing) argument order? And `mapper` is just a weaker version of `functools.partial`?

d) IMO, this falls under “not every 3 line function needs to be in the stdlib”. While much of `operator` is just a 3-line function, part of the point is that they directly reveal underlying operations that CPython implements on a deeper level (for example, with a single opcode and/or operation). This isn’t one of them. It might be better in `functools` or maybe `collections`.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [March 29, 2024, 5:59pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/3 "2024-03-29T17:59:29Z")

</div>

I came from a bit different perspective here.

I am making proxy objects, that defer evaluation. So I make various operations first and evaluate the whole structure later.

Thus, I have a node `node` and I want to be able to define all possible operations with it.

> [@MegaIng](#):
>
> a) You are aware of `operator.contains`, right?

Now `contains` doesn’t work, because if I have `node in obj`, it will call containment operator of obj, but `in_` could be used to signify the deference of the operation until the `node` evaluates.

> [@MegaIng](#):
>
> b) `operator.caller` doesn’t exists. What are the potential use-cases for `callmethod` you are seeing?

Yeah, it doesn’t… But it could.

In my case, the use case for callmethod is the same as in a)

> [@MegaIng](#):
>
> c) Having `map` and `map_` both existing is IMO a non-starter.

I named it `apply` at first, but then named it back to `map`. Does `functools.partial` allow for positional argument skipping? I did introduce sentinel `VOID` in my own `partial` implementation to allow for this. Nevertheless, I did write `mapper` to perform this for a `node` in a more lightweight manner.

> [@MegaIng](#):
>
> d) IMO, this falls under “not every 3 line function needs to be in the stdlib”.

Nah, yeah, as I said, this was a very weak proposal.

All in all, as I said, my angle is a bit different I guess.

It is more along the lines of “emulating operator behaviour from perspective of the object”. Or in other words “… from the perspective of a first term of the operation”

While it seems that current rationale of `operator` module (or the POV from which many of your arguments come from) is more like “emulating operator behaviour from perspective of the operator”

---

<div class="post-metadata">

**Author:** ![bschubert](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/bschubert/32/26920_2.png) [@bschubert](https://discuss.python.org/u/bschubert)\
**Post date:** [March 29, 2024, 6:00pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/4 "2024-03-29T18:00:45Z")

</div>

Just as a datapoint, a quick GitHub search for [`lambda a, b: a in b`](https://github.com/search?q=%22lambda+a%2C+b%3A+a+in+b%22&type=code) and [`operator.contains(b, a)`](https://github.com/search?q=operator.contains%28b%2C+a%29&type=code) does bring up a few cases where an `operator.in_` was missed. Some examples:

### Jinja2

> <https://github.com/pallets/jinja/blob/3fd91e4d11bdd131d8c12805177dbe74d85e7b82/src/jinja2/nodes.py#L41-L44>

### asteroid

> <https://github.com/pylint-dev/astroid/blob/465780a9e3c27455d6f48c7e0b0a6d1686b68b7d/astroid/nodes/node_classes.py#L1792-L1795>

### numba

> <https://github.com/numba/numba/blob/89218bb91d8ded3b573aba50d6d0967c1e25ff33/numba/cpython/builtins.py#L414-L415>

### pyanalyze

> <https://github.com/quora/pyanalyze/blob/52031c4aa09fdfc19436d7d4a5b49c93de6d2fcc/pyanalyze/name_check_visitor.py#L307-L312>

---

<div class="post-metadata">

**Author:** ![MegaIng](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/megaing/32/16162_2.png) [@MegaIng](https://discuss.python.org/u/MegaIng)\
**Post date:** [March 29, 2024, 6:17pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/5 "2024-03-29T18:17:18Z")

</div>

> [@dg-pb](#):
>
> Now `contains` doesn’t work, because if I have `node in obj`, it will call containment operator of obj, but `in_` could be used to signify the deference of the operation until the `node` evaluates.

Not sure what you mean? The magic method you need to implement for `node in obj` is ` __contains__ `. So it is actually impossible to overload this without a change in syntax, or modifying `obj` as well.

> [@dg-pb](#):
>
> Yeah, it doesn’t… But it could.

The point is you said it does. So you appear to not have paid attention to what is available. I am also not sure what `operator.caller` would do.

> [@dg-pb](#):
>
> Does `functools.partial` allow for positional argument skipping?

No, but that is a completely different topic. I don’t know how this relates to your proposal for `map` or `mapper`.

> [@dg-pb](#):
>
> while it seems that current rationale of `operator` module is more like “emulating operator behaviour from perspective of the operator”

Well, yes, that’s why the module is called `operator` 😛 While I agree that this philosophical view could be changed, I still see no real benefit for suggestions b-d

> [@bschubert](#):
>
> Just as a datapoint, a quick GitHub search for [`lambda a, b: a in b`](https://github.com/search?q=%22lambda+a%2C+b%3A+a+in+b%22&type=code) and [`operator.contains(b, a)`](https://github.com/search?q=operator.contains%28b%2C+a%29&type=code) does bring up a few cases where an `operator.in_` was missed. Some examples:

Hm, these example do suggest to me that `operator.in_` and `operator.not_in` are probably a good idea. Trying to generically do stuff like map AST nodes to actions is made slightly easier by this. But I am sure this has been discussed before, maybe it makes sense to search through the history of the `operator` module.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [March 29, 2024, 8:12pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/6 "2024-03-29T20:12:32Z")

</div>

> [@MegaIng](#):
>
> Not sure what you mean? The magic method you need to implement for `node in obj` is ` __contains__ `. So it is actually impossible to overload this without a change in syntax, or modifying `obj` as well.

You’re right. I can not emulate behaviour of the operator, but I use operator mixin (similar to what dask did [dask/dask/utils.py at b663dca0fa4ca4686b8c08f7cb30d11320012901 · dask/dask · GitHub](https://github.com/dask/dask/blob/b663dca0fa4ca4686b8c08f7cb30d11320012901/dask/utils.py#L1424)), where I automatically create operators and methods for such objects (proxies, nodes, array types, etc). So having `in`, `not_in`, I can make specifications with method names. So my object will not emulate operator behaviour, but the best of what I can have is a method created for a node object, so I can emulate it via `node.is_in(obj)`.

> [@MegaIng](#):
>
> The point is you said it does. So you appear to not have paid attention to what is available. I am also not sure what `operator.caller` would do.

I did not deny that I said it and implicitly agreed with your observation that I made a mistake. Whether I did or did not pay the attention is subject to investigation. In this case, I have my own caller and just forgot that I use my own implementation and not the `operator`. My caller implementation looks like:

```python
class caller:
    __slots__ = ('_args', '_kwds')

    def __init__ (self, *args, **kwds):
        self._args = args
        self._kwds = kwds

    def __call__ (self, obj):
        return obj(*self._args, **self._kwds)

    def __repr__ (self):
        args = list(map(repr, self._args))
        args.extend('%s=%r' % (k, v) for k, v in self._kwds.items())
        return '%s.%s(%s)' % (self. __class__. __module__ ,
                              self. __class__. __name__ ,
                              ', '.join(args))

    def __reduce__ (self):
        if not self._kwds:
            return self. __class__ , self._args
        from functools import partial
        return partial(self. __class__ , **self._kwds), self._args

```

Also, these are equivalent:  
a) `methodcaller('name', *args, **kwds)(obj)`  
b) `caller(*args, **kwds)(attrgetter('name')(obj)).`

So one way to look at is `A + B = C`, where `A = attrgetter, B = caller, C = methodcaller`. Now `A and C` exist in `operator`. If subtraction `C - A` was possible, then there would be a very weak case to implement `B`, however it is not, so having `caller` could be useful for functional completeness.

> [@MegaIng](#):
>
> > [@dg-pb](#):
> >
> > Does `functools.partial` allow for positional argument skipping?
> 
> No, but that is a completely different topic. I don’t know how this relates to your proposal for `map` or `mapper`.

This is in response to:

> [@MegaIng](#):
>
> And `mapper` is just a weaker version of `functools.partial`?

So my point is that it is not a weaker version of `functools.partial`, because `functools.partial` can not do what `mapper` can.

> [@MegaIng](#):
>
> Well, yes, that’s why the module is called `operator` 😛 While I agree that this philosophical view could be changed, I still see no real benefit for suggestions b-d

All in all, these are just proposals of things that I personally had to implement myself, while trying to achieve a complete functionality of object abstractions (Another example would be an array class which calls operators and methods over every element of it).

And yes, intuitively I felt that `in_` and `not_in` could be most useful outside of what I do.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 10, 2024, 4:18pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/7 "2024-06-10T16:18:27Z")

</div>

There is one more suggestion I would like to add: `operator.itemsetter`

Item getter has become a very useful performance boost for many problems. I think its friend `itemsetter` could be as useful.

---

<div class="post-metadata">

**Author:** ![chepner](https://avatars.discourse-cdn.com/v4/letter/c/22d042/32.png) [@chepner](https://discuss.python.org/u/chepner)\
**Post date:** [June 10, 2024, 6:40pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/8 "2024-06-10T18:40:56Z")

</div>

> [@dg-pb](#):
>
> Item getter has become a very useful performance boost for many problems. I think its friend `itemsetter` could be as useful.

`itemsetter` is more complicated from an API standpoint than `itemgetter`.  
There are multiple ways `itemsetter` could be implemented for _one_ attribute, all equivalent to `setattr(x, 'foo', v)`:

1. `itemsetter('foo', v)(x)`
2. `itemsetter('foo')(v)(x)`
3. `itemsetter(v, 'foo')(x)`
4. `itemsetter(v)('foo')(x)`

It’s not clear how, or if, you would want to support setting multiple attribute at once. If you are serious about such a proposal, you’ll have to be explicit about what exactly you are proposing, because it’s not obvious what “the” counterpart to `itemgetter` would be.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 10, 2024, 7:08pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/9 "2024-06-10T19:08:23Z")

</div>

> [@chepner](#):
>
> It’s not clear how, or if, you would want to support setting multiple attribute at once. If you are serious about such a proposal, you’ll have to be explicit about what exactly you are proposing, because it’s not obvious what “the” counterpart to `itemgetter` would be.

Thanks for reply and good points.

I am not much interested in one-arg variant. One arg variant (of any kind) will be easy to construct with [gh-119127: functools.partial placeholders by dg-pb · Pull Request #119827 · python/cpython · GitHub](https://github.com/python/cpython/pull/119827)  
E.g.:

```python
setter_a = partial(operator.setitem, Placeholder, 'a')
setter_to_1 = partial(operator.setitem, Placeholder, Placeholder 1)
setter_a_to_1 = partial(operator.setitem, Placeholder, 'a', 1)

```

Setting multiple items is what I have in mind. And the most convenient variant I believe would be number 2 in your list:

```python
setter_abc = itemsetter('a', 'b', 'c')
setter_abc_123 = setter_abc(1, 2, 3)
d = dict()
setter_abc_123(d)
print(d) # {'a': 1, 'b': 2, 'c': 3}

```

However, I see that it is more complex than `itemgetter`. It would require 1 intermediate class.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 10, 2024, 7:31pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/10 "2024-06-10T19:31:58Z")

</div>

Also, if anyone else has any thoughts on what could be useful to add to `operator`, this is a good place to add to the list.

So far I have:  
a) `operator.in_` & `operator.not_in`  
b) `operator.itemsetter` - maybe

Also, thinking about possibility of something similar to `operator.itemgetter(*idxs)(obj, *defaults)`.  
This could be a non-invasive path to implement [Indexable get method. [1,2,3].get(4) # None - #116 by dg-pb](https://discuss.python.org/t/indexable-get-method-1-2-3-get-4-none/53430/116)

---

<div class="post-metadata">

**Author:** ![ilotoki0804](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/ilotoki0804/32/14237_2.png) [@ilotoki0804](https://discuss.python.org/u/ilotoki0804)\
**Post date:** [June 11, 2024, 1:18pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/11 "2024-06-11T13:18:30Z")

</div>

Just to clarify, the actual implementation of `operator.contains` is exactly the same as the implementation of the proposed `in_` function.

> <https://github.com/python/cpython/blob/e123f74513151da53bc380bf1ee03c35cec4f4c0/Lib/operator.py#L153C1-L155C18>

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 11, 2024, 3:35pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/12 "2024-06-11T15:35:10Z")

</div>

> [@ilotoki0804](#):
>
> Just to clarify, the actual implementation of `operator.contains` is exactly the same as the implementation of the proposed `in_` function.

Not “exactly”. “note reversed operands”

---

<div class="post-metadata">

**Author:** ![storchaka](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/storchaka/32/217_2.png) [@storchaka](https://discuss.python.org/u/storchaka)\
**Post date:** [June 12, 2024, 7:43am UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/13 "2024-06-12T07:43:23Z")

</div>

> [@bschubert](#):
>
> Just as a datapoint, a quick GitHub search for [`lambda a, b: a in b`](https://github.com/search?q=%22lambda+a%2C+b%3A+a+in+b%22&type=code) and [`operator.contains(b, a)`](https://github.com/search?q=operator.contains%28b%2C+a%29&type=code) does bring up a few cases where an `operator.in_` was missed.

Note that some of these examples use lambdas even if there is corresponding `operator` function, e.g `lambda a, b: a < b` instead of `operator.lt`.

You can also find examples for other reversions, e.g. [`lambda a, b: b - a`](https://github.com/search?q=%22lambda+a%2C+b%3A+b+-+a%22&type=code). Are you going to add functions with the reversed order for all `operator` functions or only for `operator.contains`?

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 12, 2024, 3:39pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/14 "2024-06-12T15:39:55Z")

</div>

> [@storchaka](#):
>
> Are you going to add functions with the reversed order for all `operator` functions or only for `operator.contains`?

All the other operators:

```python
a <op> b

class A:
    def __opname__ (self_a, b):
        ...

```

Containment is a special case:

```python
a in b

class A:
    def __contains__ (self_b, a):
        pass

```

I don’t think reversed order can be justified in the same way for other functions.

I am not suggesting to implement `contains` in reverse order, but `in` and `not in` in natural order. Same as `is_` and `is_not`.

To me these have proven to be useful in practice. I had to implement them when writing proxy objects.

---

<div class="post-metadata">

**Author:** ![storchaka](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/storchaka/32/217_2.png) [@storchaka](https://discuss.python.org/u/storchaka)\
**Post date:** [June 12, 2024, 4:29pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/15 "2024-06-12T16:29:49Z")

</div>

It is more complicated, because they can call not only ` __op__ `, but ` __rop__ `. `operator.contains()` can also call ` __iter__ ` or ` __getitem__ `. `operator.is_()` does not call any special method.

Do you have concrete use cases for this or want to add it “for consistency”?

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 12, 2024, 5:10pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/16 "2024-06-12T17:10:58Z")

</div>

In this case it is 50-50. If there was no consistency improvement I would not propose this, but I found that such consistency was required to make functionality of deferred evaluation graph objects complete in functionality.

One case that I needed this was custom object validators:

```python
class ValidObject:
    ...

valid_obj = ValidObject()['a'].not_in([0, 1, 2])

obj1 = dict(a=1)
obj2 = dict(a=3)

valid_obj.is_valid(obj1) # False
valid_obj.is_valid(obj2) # True

```

Now obviously `contains` can be used to implement this:

```python
class ValidObject:
    def not_in(self, other):
        operator.contains(other, self)

```

But I don’t write these manually. I use mixin for adding a set of required functionality (similarly to how `dask` does it), where I have operation specifications that are added to object automatically:

```python
class ValidObject(MethodMixin):
    _methods_to_add = [NOT_IN_METHOD, SUB_METHOD]

SUB_METHOD = Namespace(name=' __sub__', func=operator.sub)
NOT_IN_METHOD = Namespace(name='not_in', func=operator.not_in)

```

There is no such issue with reversal of numeric methods, as:

```python
valid_obj = 1 - ValidObject()

```

Will correctly swap arguments.

BTW, there was a suggestion regarding `rev` methods for other functions [Reversed ops in operator module - #2 by tjreedy](https://discuss.python.org/t/reversed-ops-in-operator-module/24949/2). I have never needed any of those in practice.

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 12, 2024, 5:31pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/17 "2024-06-12T17:31:31Z")

</div>

Also, I have used `MethodMixin` for various applications: ast graphs, symbolic mathematics, deferred evaluation and several others, and `operator` functions pretty much covered all of the needs. There were just a few that I had to write myself.

There were several, which I think are specific to how I do things and there were some candidates which I thought could be of use to others and general consistency:  
a) `in_` and `not_in`  
b) `logical_or` and `logical_and` and others

a) was there for a while now so I thought maybe it is time to test the waters.

And I haven’t given enough time and thought to b) yet, but I think it could be a good candidate. E.g. [Python array API standard — Python array API standard 2023.12 documentation](https://data-apis.org/array-api/latest/) has both bitwise and logical.

---

<div class="post-metadata">

**Author:** ![encukou](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/encukou/32/2461_2.png) [@encukou](https://discuss.python.org/u/encukou)\
**Post date:** [June 13, 2024, 9:22am UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/18 "2024-06-13T09:22:09Z")

</div>

> [@dg-pb](#):
>
> `logical_or` and `logical_and`

You can’t really replace `and`/`or` with functions: they do short-circuiting. Function arguments all need to be evaluated.  
If that’s not an issue for you, and you also don’t mind getting only `True` or `False` back, you can use [`all`](https://docs.python.org/3/library/functions.html#all)/[`any`](https://docs.python.org/3/library/functions.html#any).

---

<div class="post-metadata">

**Author:** ![dg-pb](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/dg-pb/32/16248_2.png) [@dg-pb](https://discuss.python.org/u/dg-pb)\
**Post date:** [June 13, 2024, 9:26pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/19 "2024-06-13T21:26:08Z")

</div>

> [@encukou](#):
>
> You can’t really replace `and`/`or` with functions: they do short-circuiting. Function arguments all need to be evaluated.

That is true, but there are 2 components to this:  
a) logical operation  
b) short circuiting

It is impossible to immediately address b), but it doesn’t mean that having a) in `operator` module is necessarily a bad idea.

```python
opr.and_(2, 4) -> 0

```

Having logical operation, even if it does not propagate short circuiting could be useful.

P.S. Once short-circuiting is addressed properly, these functions will benefit from it too.

---

<div class="post-metadata">

**Author:** ![Rosuav](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/rosuav/32/3429_2.png) [@Rosuav](https://discuss.python.org/u/Rosuav)\
**Post date:** [June 13, 2024, 10:58pm UTC](https://discuss.python.org/t/proposed-additions-to-operator/49846/20 "2024-06-13T22:58:02Z")

</div>

> [@dg-pb](#):
>
> It is impossible to immediately address b), but it doesn’t mean that having a) in `operator` module is necessarily a bad idea.
> 
> ```python
> opr.and_(2, 4) -> 0
> 
> ```
> 
> Having logical operation, even if it does not propagate short circuiting could be useful.

If you need this, you can easily write it as a lambda function. I don’t think it belongs in the `operator` module when it has an important difference in behaviour.

[Next page](https://discuss.python.org/t/proposed-additions-to-operator/49846.md?page=2)
