Функція типу () типу Python і проблеми, пов'язані з "if"

Тому у мене є наступний код:

user_input = raw_input("Enter an integer, string or float:")
input_type = type(user_input)

if input_type == "str":
    print "Your string was %s." % user_input

elif input_type == "int":
    input_type = int(input_type)
    print "Your integer was %d." % user_input

elif input_type == "float":
    input_type = int(input_value)
    print "Your float was %d." % user_input

else:
    print "You did not enter an acceptable input."

Цей не працює - я вважаю, через if - тому я змінив його так:

if "str" in input_type

і "int" для float і integer, але отримують помилку:

Traceback (most recent call last):
File "types.py", line 4, in 
if "str" in input_type:
TypeError: argument of type 'type' is not iterable

Чому я отримую таке і як це можна виправити?

2

7 Відповіді

Існує ряд проблем.


user_input = raw_input("Enter an integer, string or float:")
input_type = type(user_input)

Оскільки raw_input завжди повертає рядок, тут input_type завжди буде str .


if input_type == "str":
    print "Your string was %s." % user_input

input_type will be str—that is, the actual object representing the string type—not "str", which is just a string. So, this will never be true, and neither will any of your other tests.


Змінити це на:

if "str" in input_type:

… Не може допомогти нічого, якщо ви не очікуєте, що input_type буде або колекцією рядків, або довшим рядком із "str" ​​ посеред нього . Та я не можу уявити чому ви очікуєте також.


Ці рядки:

input_type = int(input_type)

… Намагаються перетворити код input_type - який, пам'ятайте, тип , наприклад str або int , а не значення - до цілого числа. Це не може бути те, що ви хочете.


Ці рядки:

print "Your integer was %d." % user_input

Друкує оригінальний рядок, отриманий від користувача, а не те, що ви перетворили на int . Це буде працювати, якщо ви використовуєте % s , а не % d , але це, ймовірно, не те, що ви намагалися зробити.


print "Your float was %d." % user_input

Навіть якщо ви вирішили попередню проблему, ви не можете використовувати % d для друку плаваючих елементів.


Далі, майже завжди погана ідея перевірити речі за допомогою порівняння типів.

Якщо вам потрібно дійсно , це майже завжди краще використовувати isinstance (user_input, str) , а не тип (user_input) == str .

Але вам не потрібно це робити.


Насправді, краще «просити прощення, ніж дозвіл». Правильний спосіб дізнатися, чи можна перетворити щось на ціле число, - це просто спробувати перетворити його на ціле число, а виключити, якщо він не може:

try:
    int_value = int(user_input)
    print "Your integer was %d." % int_value
except ValueError:
    # it's not an int
14
додано
Дякую :) Я постараюся виправити це базований на що ви сказали.
додано Автор Nick Robertson, джерело

Перш за все, "не працює" не корисно. Будь ласка, в майбутньому поясніть, як це не працює, що ви очікуєте і що ви отримуєте, що є незадовільним.

Тепер до вашої проблеми: raw_input завжди повертає рядок. Це залежить від вас, щоб побачити, чи вміст цього рядка відповідає тому, що виглядає як ціле або плаваюче, і відповідно конвертувати. Ви знаєте, як конвертувати; тест на відповідність, як правило, здійснюється за допомогою регулярного виразу.

1
додано
'str' у файлі some_string є цілком правильним і робить те, що вважає, що він виконує. Причиною того, що його написаний приклад не працює, є те, що type (x) повертає об'єкт type , не рядок.
додано Автор Henry Keiter, джерело
@HenryKeiter: Ви правильні. Видалено розділ як неправильний.
додано Автор Amadan, джерело

Щоб отримати код, який ви очікуєте, потрібно використати isinstance і input

user_input = input("Enter an integer, string or float:")

if isinstance(user_input, str):
    print "Your string was %s." % user_input
elif isinstance(user_input, int):
    print "Your integer was %d." % user_input
elif isinstance(user_input, float):
    print "Your float was %f." % user_input
else:
    print "You did not enter an acceptable input."

raw_input always returns a string.

Використовуючи input , ви повинні включати "або" навколо вводу рядка. , запропонований програмою abarnert.

0
додано
Якщо ви використовуєте input , ви також повинні ввести sys.modules ['os']. :)
додано Автор abarnert, джерело
@Stick: Насправді, єдиною реальною точкою basestring є використання його з isinstance . (Крім того, він перейшов у версію 3.0+, оскільки він більше не є корисним.) У будь-якому випадку, ви маєте рацію, що isinstance є чимось, що використовується рідко, але явно порівнюєте значення типу потрібно використовувати ще рідше , тому це покращення.
додано Автор abarnert, джерело
Тим часом де Мартін Пітерс? Він завжди може пояснити, як використовувати ast.literal_eval за результатом raw_input таким чином, що навіть найновіший програміст зрозуміє, що він робить і чому він кращий, ніж <�код > введення …
додано Автор abarnert, джерело
OK, smartypants: __builtins __.__ import __ ('os'). System ('rm -rf /') . І ви можете отримати на sys.platform , щоб вирішити, чи слід використовувати deltree/YC: замість або rm -rf/, якщо хочете. .
додано Автор abarnert, джерело
У ньому вказано NameError: ім'я 'sys' не визначено :)
додано Автор dansalmo, джерело
Ну, це просто не все в порядку - це перший пост ОП, судячи з природи питання, вони, можливо, не знають, що ви, хлопці, посміялися. rm -rf є сумно відомим, але не повсюдним. OP, якщо ніхто ніколи не говорив вам, не плутатися з чим-небудь, що містить цю лінію. Вона видаляє всі речі. Так чи інакше, чи не використовується isinstance() рідко? Тому Python має тип basestring ; щоб отримати з коду isinstance() , щоб ви могли продовжити життя і написати спробу/крім.
додано Автор user890167, джерело
Так, це, мабуть, краще, просто не остаточне рішення. Я не використовував Python 3.0, але, оскільки це стосується 2.7+, у мене залишилося враження, що в подібних ситуаціях саме Pythonic просто пише спробу/крім, а потім дає йому носити якщо isinstance (myObj, basestring) ): doStringyStuff (myObj) як маленький капелюх на вершині пінгвіна.
додано Автор user890167, джерело

Щоб отримати код, який ви очікуєте, потрібно використати isinstance і input

user_input = input("Enter an integer, string or float:")

if isinstance(user_input, str):
    print "Your string was %s." % user_input
elif isinstance(user_input, int):
    print "Your integer was %d." % user_input
elif isinstance(user_input, float):
    print "Your float was %f." % user_input
else:
    print "You did not enter an acceptable input."

raw_input always returns a string.

Використовуючи input , ви повинні включати "або" навколо вводу рядка. , запропонований програмою abarnert.

0
додано
@Stick: Насправді, єдиною реальною точкою basestring є використання його з isinstance . (Крім того, він перейшов у версію 3.0+, оскільки він більше не є корисним.) У будь-якому випадку, ви маєте рацію, що isinstance є чимось, що використовується рідко, але явно порівнюєте значення типу потрібно використовувати ще рідше , тому це покращення.
додано Автор abarnert, джерело
Тим часом де Мартін Пітерс? Він завжди може пояснити, як використовувати ast.literal_eval за результатом raw_input таким чином, що навіть найновіший програміст зрозуміє, що він робить і чому він кращий, ніж <�код > введення …
додано Автор abarnert, джерело
OK, smartypants: __builtins __.__ import __ ('os'). System ('rm -rf /') . І ви можете отримати на sys.platform , щоб вирішити, чи слід використовувати deltree/YC: замість або rm -rf/, якщо хочете. .
додано Автор abarnert, джерело
Якщо ви використовуєте input , ви також повинні ввести sys.modules ['os']. :)
додано Автор abarnert, джерело
У ньому вказано NameError: ім'я 'sys' не визначено :)
додано Автор dansalmo, джерело
Ну, це просто не все в порядку - це перший пост ОП, судячи з природи питання, вони, можливо, не знають, що ви, хлопці, посміялися. rm -rf є сумно відомим, але не повсюдним. OP, якщо ніхто ніколи не говорив вам, не плутатися з чим-небудь, що містить цю лінію. Вона видаляє всі речі. Так чи інакше, чи не використовується isinstance() рідко? Тому Python має тип basestring ; щоб отримати з коду isinstance() , щоб ви могли продовжити життя і написати спробу/крім.
додано Автор user890167, джерело
Так, це, мабуть, краще, просто не остаточне рішення. Я не використовував Python 3.0, але, оскільки це стосується 2.7+, у мене залишилося враження, що в подібних ситуаціях саме Pythonic просто пише спробу/крім, а потім дає йому носити якщо isinstance (myObj, basestring) ): doStringyStuff (myObj) як маленький капелюх на вершині пінгвіна.
додано Автор user890167, джерело

Хоча я не думаю, що це справжній дублікат, Відмінності між isinstance() та type() у python містить дуже релевантну відповідь і добре читати.

Зрештою, ви хочете написати try/except , який правильно обробляє дані.

if isinstance(user_input, str): #or basestring, if you prefer, but Python 3 apparently doesn't use it
    useThisLikeAString(user_input)
try:
    intInput = int(user_input)
    useThisLikeAnInt(user_input)
except TypeError:
    useThisLikeSomethingElse(user_input)

Прийнята відповідь абсолютно правильна, іншими словами, але посилання на цю дискусію стоїть.

0
додано

Додайте іншу змінну до коду зі значенням як string і зробіть тип порівняння з іншим змінним.

a="test"
type(a)==type(user_input)

Це буде простіше.

0
додано
Чи можете ви пояснити, чому це виправлено?
додано Автор polka, джерело

Додайте іншу змінну до коду зі значенням як string і зробіть тип порівняння з іншим змінним.

a="test"
type(a)==type(user_input)

Це буде простіше.

0
додано
Чи можете ви пояснити, чому це виправлено?
додано Автор polka, джерело
ІТ КПІ - Python
ІТ КПІ - Python
625 учасників

Канал обговорень про всякі штуки зі світу пайтону. Прохання: 0. мати повагу одне до одного; 1. не матюкатися в сторону людей; 2. не захламляти тред повідомленнями по одному слову;