Найти - Пользователи
Полная версия: python type-cast
Начало » Python для экспертов » python type-cast
1
multik
сразу приведу упрощенный пример, чтобы понятна была суть вопроса

class A:
def __str__(self):
return 'abc'

print '123' + A()
# это порождает исключение
# TypeError: cannot concatenate 'str' and 'instance' objects

print '123' + str(A())
# это работает нормально
внимание, вопрос. можно ли в данном примере избежать явного приведения типов?

ps: конструкцию вида

'123%s' % A()
не предлагать ;)
Александр Кошелев
Првду люди говорят: хорошо заданный вопрос содержит в себе большую часть ответа. лишний раз в этом убедился:)
j2a
можно, переопределив для класса A операцию сложения (см. магические методы __add__, __radd__, __ladd__), но я бы не стал.
j2a
Daevaorn
Првду люди говорят: хорошо заданный вопрос содержит в себе большую часть ответа. лишний раз в этом убедился:)
(с) Роберт Шекли, Верный вопрос. :)
multik
ok. как вообще преведение типов в пайтоне работает? тоесть допустим
x = 5 + 3.4
type(x)
видно, что x приведен к float. несмотря на то, что 5 – это int. тоесть некоторое приведение типов все же имеется.
почему интерпретатор не пытается привести второй аргумент к str при конкатенации? т.е. в случае использования оператора + с правой либо левой частью – строкой.
poltergeist

>>> 5 + ‘3.5’

Traceback (most recent call last):
File “<pyshell#0>”, line 1, in <module>
5 + ‘3.5’
TypeError: unsupported operand type(s) for +: ‘int’ and ‘str’
>>>

multik
почему интерпретатор не пытается привести второй аргумент к str при конкатенации?
А должен? 5 + 3.4 - это сложение, а не конкатенация!

j2a в 3-м посте вроде всё сказал, и советую думать логично, а не так как захочется.
redixin
приводить int к float'у это еще куда ни шло, но строку к инту или наоборот в питоне не катит, этож вам не пхп какойнибудь, всетаки строгая типизация
зато не будешь голову ломать что к чему он приведет в случае с ‘5’ + 5. это спасает нас от всяких стремных глюков вроде

a = ‘1’
a + 1

a = ‘a’
a + 1

в первом случае будет сложение, во втором конкатенация? нееее, не надо нам такого
Андрей Светлов
class A:
def __str__(self):
return 'abc'
def __coerce__(self, other):
if isinstance(other, str):
return (str(self), other)
else:
return None


print '123' + str(A())
# это работает нормально
print '123' + A(), A()+'123'
# тоже работает
Для чисел подобная процедура делается через coercing. Способ довольно неоднозначный, я бы его не применял направо и налево. Но - работает.
multik
poltergeist
А должен? 5 + 3.4 - это сложение, а не конкатенация!
довод проигнорирован. в случае со строкой оператор + именно конкатенация. советовать вам ничего не буду ;)

redixin
приводить int к float'у это еще куда ни шло, но строку к инту или наоборот в питоне не катит, этож вам не пхп какойнибудь, всетаки строгая типизация
зато не будешь голову ломать что к чему он приведет в случае с ‘5’ + 5. это спасает нас от всяких стремных глюков вроде

a = ‘1’
a + 1

a = ‘a’
a + 1

в первом случае будет сложение, во втором конкатенация? нееее, не надо нам такого
такие неоднозначности решаются только в пределах спецификаций не более.
к сожалению, не в курсе как это работает в php, но возьмем, к примеру, java. там принято соглашение: оператор + если один из аргументов String у второго аргумента вызовет toString(). результат String. никакой неоднозначности нет. язык тоже строго типизированный.
соответственно для вашего примера и в первом и во-втором случаях результат строка ('11' и ‘a1’ соответственно).

Андрей Светлов
class A:
def __str__(self):
return ‘abc’
def __coerce__(self, other):
if isinstance(other, str):
return (str(self), other)
else:
return None


print ‘123’ + str(A())
# это работает нормально
print ‘123’ + A(), A()+'123'
# тоже работает
Андрей Светлов
Для чисел подобная процедура делается через coercing. Способ довольно неоднозначный, я бы его не применял направо и налево. Но - работает.
спасибо! а применять приходится не потому что мне так захотелось, а потому что есть набор требований на модуль и есть код библиотеки, который я не могу менять по лицензионным ограничениям.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB