Вы получили ответы, но ни один, это не кажется, что на самом деле делает то, что вы спрашиваете. Вот еще одна возможность, которая может подойти ближе ...:
import numbers
def distance_from_zero(d=None):
while not isinstance(d, numbers.Real):
try: d = float(raw_input('please enter a number'))
except ValueError: print('{!r} is not a number'.format(d))
print(abs(d))
return abs(d)
[Добавлено: значение по умолчанию, не номер для d
только в случае, если вы хотите, чтобы иметь возможность вызвать функцию без аргументов силы пользовательского ввода , а не только позволяют это, как вы сформулировали Q; ниже).
(Если Python 3, используйте input
вместо raw_input
).
Это использование «гусиной печати» - проверяет абстрактный базовый класс numbers.Real
, охватывая все числа, кроме сложных (если вам тоже нравятся сложные номера, используйте вместо этого numbers.Number
). Он набирает ноль или больше раз, пока, наконец, d
не является допустимым числом (если вам тоже нравятся сложные номера, используйте complex
вместо float
), затем выполняет работу.
(Эта проверка против абстрактного базового класса [aka ABC], известного как «гусиная типизация», часто, хотя и не всегда предпочтительнее более общего подхода «утиная печать», я также выступаю - грубо говоря, гусь лучше чем утка, когда ABC уже существует, что идеально подходит для ваших потребностей, но не иначе).
Это может быть не самая лучшая архитектура, так как она объединяет две проблемы: обеспечение того, чтобы d
было числом, а затем что-то с ним (в этом случае печатаем и возвращаем его абсолютное значение). Особенно в крупномасштабном программировании «разделение проблем» - отличная идея - использовать отдельные блоки (функции, классы, модули и т. Д.) Для решения отдельных проблем, объединить их на уровне «оркестровки», используемый.
Это может быть преждевременным беспокойством за уровень мастерства в программировании, но на самом деле это не так сложно, как слияние проблем. То есть, вы можете иметь def ensure_number(d):
функцию, которая просто делает петлю while
выше, а затем возвращает d
когда это приемлемо количество и функцию отдельныйshow_abs
, который просто делает то print
и return
из abs(d)
.
Если вы сделали это, то ваша функция «более высокого уровня абстракции» будет проще, просто делегируя два других функций ...:
def distance_from_zero(d=None):
d = ensure_number(d)
return show_abs(d)
Посмотрите, как много «чистый» это, по сравнению к взаимопониманию? Значимое имя для подблоков (здесь простые функции) ensure_number
и show_abs
облегчают читаемость и четкость.
Кроме того, вы можете повторно использовать один или оба из этих «строительных блоков», если они вам нужны в другом месте вашей программы, просто повторив эти функции нижнего уровня, избегая «кардинального греха копирования и вставки» и уважая основной принцип программирования «СУХОЙ» («Не повторяй себя»).
В любом случае, это вам необходимо рассмотреть. Я думаю, что никогда не рано учиться в программировании (пожизненное занятие), чтобы получить хорошие привычки!)
Обратите внимание, что (если вы вообще настаиваете на проверке типа), это должно быть 'if isinstance (d, (int , float)) ', а в 2.x есть также' long'. – jonrsharpe
... чтобы добавить к этому, вы должны избегать проверки типа в пользу утиного ввода. –
@JoelCornett, современный подход ** goose typing ** еще лучше - 'isinstance (d, numbers.Real)' в этом случае (так как я - возможно, незаслуженно - зачислен на wikipedia по термину/концепции «Утка набрав», я думаю, я получаю слово :-) - или 'numbers.Number', если« complex »также является приемлемым. –