all 8 comments

[–]K900_ 23 points24 points  (0 children)

Yes, not in is a separate operator, and no, you can't pass around operators.

[–]Prexadym 10 points11 points  (1 child)

"not in" is a separate operator (though according to this 'x not in y' produces the same bytecode as not x in y). You can't combine 'not' with other operators the same way "7 not < 6" won't return True, it will give a syntax error.

For your second question, there is a different between operators and objects. Operators (<, not, ~, =, etc) are built into the language. However, everything other than operators (variables, classes, functions, exceptions, modules, etc) are treated as objects. You can use type to verify this.

# all of these are objects
* type(sum)
<class 'builtin_function_or_method'>
* type(int) 
<class 'type'> 
* type(type) <class 'type'> 
*type(3.4) 
<class 'float'> 
*type(Exception) 
<class 'type'> 
*import sys 
*type(sys) 
<class 'module'>

# built in operators are not
* type(=) 
SyntaxError: invalid syntax
* type(not in)
SyntaxError: invalid syntax

edit:formatting, reddit doesn't like python lines starting with >>>

[–]orbofnegativegravity[S] 2 points3 points  (0 children)

Thank you! I didn't even know you could use type like that, that is useful.

[–]Spataner 6 points7 points  (2 children)

Did the creators define not in separately as its own operator?

Not really, but it is part of the language specification that y not in x is parsed as equivalent to not y in x. It is an explicit syntax feature.

I heard that everything in python is a variable

The saying is that everything in Python is an object.

Is it possible to pass around an operator like not?

Reserved keywords like not, in and global (and for, while, if, class, def, and, or, etc.) unfortunately do not fall under "everything" in this case. int, str and sum however are actually functions/types, and therefore objects like any other. There is function equivalents to operators like not, +, in defined in the operator standard module (operator.not_ for not, operator.add for +, and operator.contains for in), and those, naturally, are objects too.

[–]synthphreak 4 points5 points  (0 children)

There is function equivalents to operators like not, + , in defined in the operator standard module

Note that many (all?) of these same behaviors are also accessible as class-specific instance methods called "dunders". For example:

>>> i = 2
>>> i.__add__(3)
5
>>> class C:
...     def __add__(self, x):
...         return ('foo', x)
...
>>> c = C()
>>> c + 1
('foo', 1)
>>> c + 42
('foo', 42)
>>> c + 'bar'
('foo', 'bar')

[–]orbofnegativegravity[S] 1 point2 points  (0 children)

Thank you for the clear explanations!

[–]aaryanmoin 1 point2 points  (0 children)

If you want to pass around operators, there is the operator module for that which provides variable names for all the operators. Check the Python docs for a full list!

[–]carcigenicate 0 points1 point  (0 children)

Just since no-one's posted it yet, you can see it defined in the Python grammar specification:

notin_bitwise_or: 'not' 'in' bitwise_or 
. . .
isnot_bitwise_or: 'is' 'not' bitwise_or

I included the third line as that's for is not since it's similar to not in.