Есть идеи, почему оператор else не справляется с этим?

Это мой первый маленький проект Python, начатый с нуля. Идея состоит в том, чтобы взять пользовательский ввод и вернуть "е" с указанным количеством цифр, указанным с помощью ввода пользователя. Это определенно непифонический способ ведения дел, но моей целью было попытаться решить его без посторонней помощи:)

Я использую Python 2.7, как вы можете видеть.

euler = 2.71828

digits = raw_input('Please enter the desired digit: ')

digitsError = 'Error: Please enter an integer'

euler_str = str(euler)

Я ожидал, что оператор "else" будет обращаться к нецелочисленному вводу. Однако я получил сообщение об ошибке (ValueError).

def digitsCheck():
    if digits == int:
        return digits
    else:
        return digitsError

digitsCheck()

Я решил вернуться к ошибкам и исключениям и понял, что могу использовать "попробовать / кроме / наконец" и т. Д.

try:
    print('3'+euler_str[1:int(digits)+2])
except ValueError:
    print(digitsError)

Это, вероятно, очень простая проблема, но я вновь обратился к материалу, который использовал для изучения Python, и не могу точно определить проблему. Спасибо вам большое!

edit: сообщение об ошибке, упомянутое выше:

ValueError: invalid literal for int() with base 10:

Я получаю это сообщение, когда использую нецелое число с raw_input().

2 ответа

Решение

Проблема, с которой вы столкнулись, связана с концепцией, называемой областью действия. С точки зрения программирования область действия - это способ, которым система использует переменные во время выполнения программы. Для простоты поговорим о двух переменных:

  • Глобальный: увиденный всем
  • Местный: видят только некоторые вещи

Когда программа выполняет функцию и переменную, скажем myVar инициализируется внутри этой функции, она выбрасывается в стек. Как только функция заканчивает выполнение, локальная переменная выталкивается из стека и больше не может быть использована в пространстве памяти. Напротив, глобальная переменная выбрасывается в стек во время выполнения программы и на нее можно ссылаться в любое время до завершения программы, поскольку она будет оставаться в стеке до этого времени. Общее правило: глобальные переменные редко бывают предпочтительными, просто используйте локальные переменные и полагайтесь на область видимости функции.

Это может показаться немного сложным, если вы не прошли курс компьютерной архитектуры, поэтому:

global myVar # technically program starts here, allocates memory on the stack for 'myVar'

def local(): # Notice there are no function parameters
    print (myVar) # myVar is accessible outside this local function

def change(): # Again, no parameters
    myVar = 'World' # Again, accessible
    local()

# Program starts here
myVar = 'Hello'
local()
change()

# Outputs:
# 'Hello'
# 'World'

Теперь, если я попробовал то же самое с локальными переменными:

def local():
    print (myVar)

def change():
    myVar = 'World'
    local()

myVar = 'Hello'
local()
change()

# Outputs:    
# Will not output, will thrown error saying `myVar` is not defined

Причина, по которой это не сработает, заключается в том, что в local() называется myVar; эта переменная определена вне области действия функции. Чтобы исправить эту проблему, мы передаем переменную, таким образом, перенося в область требуемой функции:

def local(var): # var == myVar
    print (var)

def change(var): # var == myVar
    var = 'World'
    local(var)

myVar = 'Hello' # Start with a main local variable
local(myVar) # Give it to 'local()'
change(myVar) # Give it to 'change()'

# Outputs:    
# 'Hello'
# 'World'

Наконец, мы можем взглянуть на ваш случай:

def digitsCheck(): # This is a local function
    if digits == int: # Interpreter is wondering "What is digits?"
        return digits
    else:
        return digitsError # Interpreter is wondering "What is digitsError?"

euler = 2.71828 # Constant
digits = raw_input('Please enter the desired digit: ') # Local variable
digitsError = 'Error: Please enter an integer' # Local variable
euler_str = str(euler) # Local variable

digitsCheck() # Call to local function [but this also returns, how do you capture?]

Пара заметок:

  • raw_input возвращает str
  • Объявите свои константы (euler) вверху файла и в CAPS
  • Может быть немного продвинутым, но ваш digistError уже является встроенным исключением (ValueError)
  • Ваш digitsCheck() имеет return позвоните, но вы не получите ответ
  • Ваш digitsCheck() пытается digits == int но это не сработает вообще

Что бы я сделал:

EULER = 2.71828

def digitsCheck():
    # You don't even need this!

while True:
    try:
        digits = int(raw_input('Please enter the desired digit: ')
        break
    except ValueError:
        print('Error: Please enter an integer')

euler_str = str(EULER) # For whatever you use this for

# Rest of your program below

Я твердо верю в примеры, дополняющие концепцию, так что, надеюсь, это помогло!

Когда вы делаете if digits == int:сравниваешь переменную digits (который содержит строку, возвращаемую raw_input) с типом int, Это сравнение никогда не будет истинным, поскольку строка и тип никогда не равны. Большую часть времени объекты разных типов не будут равны. Числа являются существенным исключением, где эквивалент int а также float экземпляры будут сравниваться как равные (например, 1.0 == 1).

Возможно, вы хотели проверить, если digits переменная содержит фактическое целочисленное значение, в этом случае вы можете использовать isinstance: if isinstance(digits, int):, Но мы знаем digits это строка, так как это единственное, что raw_input когда-нибудь вернется. Даже числовая строка является строкой, а не целым числом.

Вы хотите проверить, все ли символы в digits строка на самом деле является цифрой, так что вы можете успешно передать значение int чтобы получить число, а не строку. Для этого вы, вероятно, хотите позвонить isdigit метод в строке: if digits.isdigit():,

Но это подход "Look Before You Leap" (LBYL) к проблеме преобразования пользовательского ввода в число. Ваше второе решение с использованием try а также except использует подход, известный как "Проще просить прощения, чем разрешения" (EAFP), который часто предпочитают многим программистам Python над стилем LBYL в ситуациях, когда это легко сделать. Если вы только изучаете программирование на Python, определенно стоит научиться писать код в обоих стилях, поскольку в некоторых случаях один стиль будет проще, чем другой, для конкретной задачи.

Другие вопросы по тегам