Операторы Python, возвращающие целые числа - PullRequest
4 голосов
/ 06 мая 2010

Есть ли способ, чтобы операторы Python line "==" и ">" возвращали целые числа вместо bools. Я знаю, что могу использовать функцию int (int(1 == 1)) или добавить 0 ((1 == 1) + 0), но мне было интересно, есть ли простой способ сделать это. Например, если вы хотите, чтобы деление возвращало числа с плавающей запятой, вы можете набрать from __future__ import division. Есть ли способ сделать это с операторами, возвращающими целые числа? Или я могу создать класс, расширяющий __future__._Feature, который будет делать то, что я хочу?

Ответы [ 6 ]

3 голосов
/ 06 мая 2010

Вы не можете переопределить встроенные функции сравнения. В некотором смысле операторы сравнения уже возвращают int. bool является подклассом int, поэтому вы можете сделать с ним все, что можете сделать с int. Тогда возникает вопрос: почему вы хотите, чтобы сравнения возвращали объекты int, а не объекты bool?

1 голос
/ 06 мая 2010

Для ваших собственных объектов легко переопределить каждый оператор сравнения. Для встроенных методов переопределения «только для чтения», поэтому все мои попытки их установки не удаются.

>>> class foo:
   def __lt__(self, other):
      return cmp(5, other)

>>> f = foo()
>>> f<3
1
>>> f<7
-1
>>> f<5
0

>>> j=""
>>> j.__lt__=lambda other: cmp(5, other)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'str' object attribute '__lt__' is read-only
1 голос
/ 06 мая 2010

Исходя из вашего пояснения, вы можете изменить оператор сравнения на что-то вроде:

stack.push(1 if stack.pop() > stack.pop() else 0)

Это преобразует логический результат > в 1 или 0, как вам бы хотелось.

Кроме того, будьте осторожны при вызове stack.pop() дважды в одном выражении.Вы не знаете (наверняка), в каком порядке будут оцениваться аргументы, и разные реализации Python вполне могут вывести аргументы в другом порядке.Вам нужно будет использовать временные переменные:

x = stack.pop()
y = stack.pop()
stack.push(1 if x > y else 0)
1 голос
/ 06 мая 2010

Вы можете сделать так, чтобы операторы сравнения ваших пользовательских классов возвращали все, что вам нравится - просто реализуйте соответствующие методы (__eq__, __ne__, __gt__, __lt__, __ge__, __le__) вернуть то, что вы хотите. Для объектов, которые вы не контролируете, вы не можете это изменить, но в этом нет необходимости: bools - это целые, из-за принципа замены Лискова . Код, который замечает разницу между логическим значением, возвращаемым методами __eq__ встроенных типов, и любым другим целым числом, использует неверный результат.

Модуль __future__ здесь не актуален; вы не можете использовать его, чтобы делать все, что вы хотите, вы можете использовать его только для изменения определенных настроек, которые были добавлены в Python. Вы можете превратить деление в истинное деление с помощью импорта __future__, потому что это то, что было добавлено в Python. Единственный способ добавить больше __future__ импорта - это изменить сам Python.

0 голосов
/ 06 мая 2010

Нет, вы не можете. Когда Гвидо унифицировал типы и классы, он нашел способ переопределить поведение встроенных типов (благодаря тому, как он реализовал вещи), но он объявил это ошибкой и закрыл лазейку. Изменение поведения встроенных типов (кроме вашего примера - импортирование деления из будущего, которое есть по уважительной причине) запрещено.

Извините, но я не могу найти сообщение в списке рассылки. Я помню это, хотя это было довольно интересно.

0 голосов
/ 06 мая 2010

Приведите свой bool к int?

>>> int(True)

1

>>> int(False)

0

Или передали это на улицу?

>>> str(int(True))

'1'

>>> str(int(False))

'0'

...