gehbiszumeis
gehbiszumeis

Reputation: 3711

Everything in Python is an object, why operators are not?

Everything in Python is an object

We all know this sentence and all Pythonistas (including me) loving it. In that regard, it is interesting to look at operators. They seem to be no objects, e.g.

>>> type(*)     # or /, +, -, < ...

returns SyntaxError: invalid syntax.

However, there might be situations where it would be useful to have them treated as objects. Consider for example a function like

def operation(operand1, operand2, operator):
    """
    This function returns the operation of two operands defined by the operator as parameter
    """

    # The following line is invalid python code and should only describe the function
    return operand1 <operator> operand2

So operation(1, 2, +) would return 3, operation(1, 2, *) would return 2, operation(1, 2, <) would return True, etc...

Why is this not implemented in python? Or is it and if, how?


Remark: I do know the operator module, which also wouldn't be applicable in the example function above. Also I am aware that one could workaround it in a way like e.g. operations(operand1, operand2, '>') and find the desired operation via the string representation of the corresponding operator. However I am asking for the reason of the non-existance of operator-objects being able to be passed as parameters in functions e.g. like every other python object.

Upvotes: 3

Views: 659

Answers (5)

Francisco Costa
Francisco Costa

Reputation: 141

Here is an example of an excellent question.
Technically speaking to answer properly to this question one would could use the Lexical Analyser (tokenizer) approach, in terms of token categories, besides encoding declarations, comments and blank lines.

Besides Operator, also: i) NEWLINE, INDENT and DEDENT, ii) Keywords, and iii) Delimiters are not objects. Everything else is an object in Python.

So next time they tell you "Everything in Python is an object" you should answer:
"Everything in a logical line that is not NEWLINE, INDENT, DEDENT, Space bar Character, Operator, Keyword or Delimiter is an object in Python."

The rationale attempt in here: When Python designers devised the language they figured that these token categories where pretty much useless to be treated as objects, in any situation, that could not be otherwise solved by other means.
Cheers.

Upvotes: 1

Stefan Pochmann
Stefan Pochmann

Reputation: 28646

You say:

    # The following line is invalid python code and should only describe the function
    return operand1 <operator> operand2

That's not true, that code isn't invalid. And with a fitting operator, it does work as intended:

def operation(operand1, operand2, operator):
    """
    This function returns the operation of two operands defined by the operator as parameter
    """
    return operand1 <operator> operand2

class Subtraction:
    def __gt__(self, operand):
        try:
            return self.operand - operand
        except:
            self.operand = operand
            return self

print(operation(13, 8, Subtraction()))

Prints 5 as expected.

Upvotes: 0

wong.lok.yin
wong.lok.yin

Reputation: 889

You can think operator as a kind of syntax sugar. For example, 3+4 is just a syntax sugar of int.__add__(3,4). And type(int.__add__) is not None but type(+) will raise error.

Upvotes: 0

r.ook
r.ook

Reputation: 13898

Operators tell the interpreter what underlying method to operate on the objects provided, so they are more like functions, which are still object in a sense, you just need the appropriate reference to call the type on. For instance, say you have Foo.some_method and you want to look up its type. You need the proper reference: type(Foo.some_method) instead of just type(some_method), the first of which returns <class 'function'>, the latter a NameError.

That said, you can certainly implement something like this without the operator module:

def operation(operand1, operand2, operator):
    return getattr(operand1, operator)(operand2)

operation(1, 2, '__add__')
# 3

That said, the easiest way to understand your issue is that operators are part of the syntax for python to interpret your code, not an actual object. So when the interpreter sees *, +, ~ etc... it expects two operands to fetch the aliased method and execute. The method itself is an object. The syntax, not so much.

Upvotes: 4

chepner
chepner

Reputation: 532053

Every value is an object. Operators are not values; they are syntax. However, they are implemented by functions, which are values. The operator module provides access to those functions.


Not at all applicable to Python, though suggestive, is that a language could provide additional syntax to convert an operator into a "name". For example, in Haskell, you can use an infix operator like + as if it were a name using parentheses. Where you wanted to write operation(3, 5, +) in Python, Haskell allows operation 3 5 (+).

There's no technical reason why something similar couldn't be added to Python, but there's also no compelling design reason to add it. The operator module is sufficient and "fits" better with the language design as a whole.

Upvotes: 7

Related Questions