long for float convert concatenate cast python type-conversion typeerror object-to-string

for - list to int python



Error de Python3: TypeError: no se puede convertir el objeto ''bytes'' a str implicitly (3)

Estoy trabajando en el ejercicio 41 en learnpythonthehardway y sigo recibiendo el error:

Traceback (most recent call last): File "./url.py", line 72, in <module> question, answer = convert(snippet, phrase) File "./url.py", line 50, in convert result = result.replace("###", word, 1) TypeError: Can''t convert ''bytes'' object to str implicitly

Estoy usando python3 mientras los libros usan python2, así que hice algunos cambios. Aquí está el guión:

#!/usr/bin/python # Filename: urllib.py import random from random import shuffle from urllib.request import urlopen import sys WORD_URL = "http://learncodethehardway.org/words.txt" WORDS = [] PHRASES = { "class ###(###):": "Make a class named ### that is-a ###.", "class ###(object):/n/tdef __init__(self, ***)" : "class ### has-a __init__ that takes self and *** parameters.", "class ###(object):/n/tdef ***(self, @@@)": "class ### has-a funciton named *** that takes self and @@@ parameters.", "*** = ###()": "Set *** to an instance of class ###.", "***.*** = ''***''": "From *** get the *** attribute and set it to ''***''." } # do they want to drill phrases first PHRASE_FIRST = False if len(sys.argv) == 2 and sys.argv[1] == "english": PHRASE_FIRST = True # load up the words from the website for word in urlopen(WORD_URL).readlines(): WORDS.append(word.strip()) def convert(snippet, phrase): class_names = [w.capitalize() for w in random.sample(WORDS, snippet.count("###"))] other_names = random.sample(WORDS, snippet.count("***")) results = [] param_names = [] for i in range(0, snippet.count("@@@")): param_count = random.randint(1,3) param_names.append('', ''.join(random.sample(WORDS, param_count))) for sentence in snippet, phrase: result = sentence[:] # fake class names for word in class_names: result = result.replace("###", word, 1) # fake other names for word in other_names: result = result.replace("***", word, 1) # fake parameter lists for word in param_names: result = result.replace("@@@", word, 1) results.append(result) return results # keep going until they hit CTRL-D try: while True: snippets = list(PHRASES.keys()) random.shuffle(snippets) for snippet in snippets: phrase = PHRASES[snippet] question, answer = convert(snippet, phrase) if PHRASE_FIRST: question, answer = answer, question print(question) input("> ") print("ANSWER: {}/n/n".format(answer)) except EOFError: print("/nBye")

¿Qué estoy haciendo exactamente mal aquí? ¡Gracias!


Convierte explícitamente el tipo de byte ''palabra'' en una cadena

result = result.replace("###", sre(word), 1)

deberia de funcionar


En Python 3, la función urlopen devuelve un objeto HTTPResponse , que actúa como un archivo binario. Entonces, cuando haces esto:

for word in urlopen(WORD_URL).readlines(): WORDS.append(word.strip())

... terminas con un grupo de objetos de bytes lugar de objetos str . Entonces cuando haces esto:

result = result.replace("###", word, 1)

... terminas tratando de reemplazar la cadena "###" dentro del result la cadena con un objeto bytes , en lugar de un str . De ahí el error:

TypeError: Can''t convert ''bytes'' object to str implicitly

La respuesta es decodificar explícitamente las palabras tan pronto como las obtengas. Para hacer eso, debes averiguar la codificación correcta de los encabezados HTTP. ¿Cómo haces eso?

En este caso, leo los encabezados, puedo decir que es ASCII, y obviamente es una página estática, así que:

for word in urlopen(WORD_URL).readlines(): WORDS.append(word.strip().decode(''ascii''))

Pero en la vida real, generalmente necesita escribir un código que lea los encabezados y lo descubra dinámicamente. O mejor, instale una biblioteca de nivel superior como requests , que hace eso automáticamente .