2010-05-05 3 views
4

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

+1

Это кажется довольно странным запросом, без ясной мотивации. Вы хотели бы объяснить немного больше о том, почему вы считаете, что вам это нужно? –

+0

Я создаю язык программирования на основе стека. Если вы используете больше или меньше, чем в нем, он выталкивает два элемента из стека и делает что-то вроде 'stack.push (stack.pop()> stack.pop())'. Если бы я захотел напечатать целое число, то он взял верхнюю часть стека и преобразовал бы его в строку с помощью 'str (stack.pop())' и напечатал это. Я бы хотел, чтобы 1 или 0 был напечатан, но вместо этого он печатает «True» или «False». Это создает сложности при создании таких вещей, как if. – None

+5

Изменение фундаментальных операторов в Python - не ответ. Вы либо не хотите, чтобы Python> (записывали свою собственную функцию), либо вам нужно другое поведение для преобразования булевых строк в строки (напишите свою собственную функцию). –

ответ

1

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

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) 
+0

Я использовал разные 'stack.pop()' s в коде, но пытался скомпоновать их в своем комментарии. В любом случае, спасибо. – None

+0

Порядок оценки выражений указан в справочной системе языка (http://docs.python.org/reference/expressions.html#evaluation-order). Это говорит о том, что функциональные вызовы с побочными эффектами внутри нетривиального выражения обычно являются плохими идеями. –

3

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

1

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

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

1

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

>>> 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 
0

Включите ваш bool в int?

>>> int(True)

1

>>> int(False)

0

Или бросить, что на ул?

>>> str(int(True))

'1'

>>> str(int(False))

'0'

0

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

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

Смежные вопросы