Все в Python является объектом, почему операторы не являются? - PullRequest
2 голосов
/ 10 января 2020

Все в Python является объектом

Все мы знаем это предложение, и все питонисты (включая меня) любят его. В связи с этим интересно посмотреть на операторов. Похоже, они не являются объектами, например,

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

возвращает SyntaxError: invalid syntax.

Однако могут быть ситуации, когда было бы полезно рассматривать их как объекты. Рассмотрим, например, такую ​​функцию, как

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

Так что operation(1, 2, +) вернет 3, operation(1, 2, *) вернет 2, operation(1, 2, <) вернет True, и т. c ...

Почему это не реализовано в python? Или это так, и если, как?


Примечание : Я знаю модуль operator, который также не применим в примере функция выше. Также я знаю, что можно обойти это таким образом, как, например, operations(operand1, operand2, '>') и найти нужную операцию через строковое представление соответствующего оператора. Однако я спрашиваю о причине того, что оператор-объекты не могут быть переданы в качестве параметров в функции, например, как и любой другой объект python.

Ответы [ 4 ]

5 голосов
/ 10 января 2020

Каждое значение является объектом. Операторы не являются значениями; они синтаксис. Однако они реализуются функциями, которые являются значениями. Модуль operator обеспечивает доступ к этим функциям.


Совсем неприменимо к Python, хотя и наводит на мысль, что язык может предоставлять дополнительный синтаксис для преобразования оператора в «имя». Например, в Haskell вы можете использовать инфиксный оператор, такой как +, как если бы это было имя с использованием скобок. Там, где вы хотели написать operation(3, 5, +) в Python, Haskell позволяет operation 3 5 (+).

Нет технической причины, по которой нечто подобное нельзя добавить в Python, но нет и веской конструкции причин для ее добавления. Модуль operator достаточен и лучше подходит для языкового дизайна в целом.

1 голос
/ 10 января 2020

Операторы сообщают интерпретатору, что лежит в основе метода для работы с предоставленными объектами, поэтому они больше похожи на функции, которые в некотором смысле все еще являются объектами, вам просто нужна соответствующая ссылка для вызова type на. Например, скажем, у вас есть Foo.some_method, и вы хотите посмотреть его тип. Вам нужна правильная ссылка: type(Foo.some_method) вместо просто type(some_method), первый из которых возвращает <class 'function'>, последний - NameError.

Тем не менее, вы, безусловно, можете реализовать что-то подобное без operator module:

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

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

Тем не менее, самый простой способ понять вашу проблему - это то, что операторы являются частью синтаксиса для python для интерпретации вашего кода, а не фактического объекта. Поэтому, когда интерпретатор видит *, +, ~ et c ... он ожидает, что два операнда извлекают псевдоним и выполняют метод. Сам метод является объектом. Синтаксис не так уж и много.

0 голосов
/ 10 января 2020

Вы говорите:

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

Это не правда, этот код не является недействительным. А с фитингом operator он работает как задумано:

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()))

Печать 5, как и ожидалось.

0 голосов
/ 10 января 2020

Вы можете рассматривать оператор как своего рода синтаксис сахара. Например, 3+4 - это просто синтаксический сахар int.__add__(3,4). И type(int.__add__) - это не None, но type(+) вызовет ошибку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...