Защо int(string) дава грешка в стойността

Просто се чудех защо, когато взема цяло число от низ като int('string'), защо получавате грешка в стойността в Python 3.2, а не грешка в типа. Виждам, че определението за грешка в типа е дефинирано на сайта на Python по следния начин: Повишава се, когато операция или функция се прилага към обект от неподходящ тип. Свързаната стойност е низ, даващ подробности за несъответствието на типа.

int не е ли операторът и низът е неподходящ тип? Когато правя това, получавам ValueError и не разбирам причината за това.

Ето кода. Така че, когато инстанцирам класа с ранг, който има низ за опит и нарочно получавам грешка, получавам valueerror, а не тип, както бих очаквал.

class Card:

#attributes
list_rank=   ["","Ace","2","3","4","5","6","7","8","9","10","Jack","Queen","King"]
list_suit={"d":"diamonds","c":"clubs","h":"hearts","s":"spades"}

#initialize rank and suit
def __init__(self,rank,suit):



self.rank=int(rank)

self.suit=suit




#return the rank of the card
def getRank(self):
    return(self.list_rank[self.rank])

#return the suit of the card
def getSuit(self):
    return(self.list_suit[self.suit])



#value of the cards
def bjValue(self):
    if(self.rank<10):
        return(self.rank)
    else:
        return(10)


#return the rank and suit of the card
def __str__(self):

    return (self.list_rank[self.rank]+" of "+self.list_suit[self.suit])

person user3630439    schedule 12.02.2015    source източник
comment
всеки символ има цяло число, наречено ASCII, наясно ли сте с това?   -  person m0bi5    schedule 12.02.2015
comment
Колкото и да си струва, Python 2.x също повдига ValueError.   -  person Frerich Raabe    schedule 12.02.2015
comment
Всъщност прилагате тази функция към нещо?   -  person SierraOscar    schedule 12.02.2015
comment
int не е оператор, това е вграден клас. И когато извикате int(x), вие извиквате конструктора на този клас.   -  person Frerich Raabe    schedule 12.02.2015
comment
За протокола, получаването на TypeError няма да ви помогне, ако се опитвате да направите int("Ace")   -  person David Reeve    schedule 12.02.2015
comment
Не знаех, че всеки символ има цяло число, наречено ASCII. Благодаря.   -  person user3630439    schedule 12.02.2015
comment
Обърнете внимание, че 'string' е валидно число при основа 36, т.е. int('string', base=36) се оценява на 1743045676 (десетично). ;-)   -  person Frerich Raabe    schedule 12.02.2015
comment
@FrerichRaabe благодаря, че добави към общото объркване :D   -  person André Laszlo    schedule 12.02.2015
comment
Благодаря на всички за помощта.   -  person user3630439    schedule 12.02.2015


Отговори (3)


За да разберете разликата, трябва да разберете разликата между тип и стойност. Типът на "abc" е низ, който можете да проверите, като стартирате

type("abc")  # -> string

Стойността на литерала "abc" е просто самата стойност. Ако имате израз като "ab" + "c", стойността също ще бъде "abc".

Ето защо получавате ValueError, а не TypeError; int очаква string, което сте му дали - така че е правилният тип - но value трябва да бъде нещо, което може да се интерпретира като цяло число, а "abc" очевидно не е цяло число.

За да изпробвате това, вижте разликата между:

int('abc')
# throws:
# ValueError: invalid literal for int() with base 10: 'abc'

и

int(None)
# throws:
# TypeError: int() argument must be a string or a number, not 'NoneType'

Фактът, че "abc" не изглежда веднага като цяло число, обаче не ни пречи да го тълкуваме като едно. В друга база все още може да се тълкува като число.

Например: двоичните числа, както вероятно знаете, използват само 0s и 1s, а шестнадесетичните числа обикновено се представят с помощта на цифрите 0 - 9 и буквите a - f. Функцията int приема незадължителен аргумент, който й казва коя база да използва, така че ако се опитаме да интерпретираме "abc" отново, но като шестнадесетично число, получаваме:

int('abc',  base=16)
# returns 2748
person André Laszlo    schedule 12.02.2015
comment
Благодаря много. Сега това има много повече смисъл. Не мислех наистина, предполагам. Благодаря отново. - person user3630439; 12.02.2015

защото int() приема низ като параметър, например int('1') ще изведе 1. така че '1' е подходяща стойност, но 'a' не е

person muhammedabuali    schedule 12.02.2015
comment
@user3630439 Въпросът е, че предаването на низ към конструктора int не е грешка на типа - много низове са валидни (напр. "12345"). Така че повдигането на грешка в типа за низ няма смисъл (но вдигането на грешка в типа за например None е напълно правдоподобно, както демонстрира Андре Ласло). - person Frerich Raabe; 12.02.2015
comment
тъй като 'a', както казах, е грешна стойност, тъй като не е цяло число, но '1' е приета стойност. имайте предвид, че и двете имат един и същи тип - person muhammedabuali; 12.02.2015
comment
Ааа това има смисъл. Благодаря много! - person user3630439; 12.02.2015

TL;DR: Получавате ValueError, ако предоставените от вас данни са правилния тип за функцията, която се опитвате да използвате, но стойността няма смисъл. Получавате TypeError, ако функцията, която се опитвате да използвате, не разбира какво да прави с типа на данните, които предоставяте.

Примери:

Например:

int('123') 
>>>>123

int('somestring')
>>>>Traceback (most recent call last):
    File "<interactive input>", line 1, in <module>
    ValueError: invalid literal for int() with base 10: 'somestring'

така че се опитва да преобразува низа в int, използвайки база 10, където само знаците 0-9 имат смисъл. По същество Python казва „Очаквах низ, но не разбирам този низ“

Сравнете това с това:

>>>>int('FF', base=16)  #hexadecimal
255

>>>>int('9', base=8) # can only use 0-7 in octal
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
ValueError: invalid literal for int() with base 10: 'somestring'


>>>>int('somestring', base=36)
2913141654103084L

(База 36 използва 0-9 след това a-z като валидни цифрови знаци)

Ако се опитате да използвате напълно грешен тип, като например int( {'apple':1} ), тогава получавате TypeError и полезно съобщение, което ви казва защо не работи:

Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
TypeError: int() argument must be a string or a number, not 'dict'
person Danny    schedule 12.02.2015
comment
Благодаря за чудесното обяснение! Оценявам го! - person user3630439; 12.02.2015