Python3 错误:类型错误:无法将“字节”对象隐式转换为 str
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16699362/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python3 Error: TypeError: Can't convert 'bytes' object to str implicitly
提问by thewooster
I am working on exercise 41 in learnpythonthehardway and keep getting the error:
我正在 learnpythonthehardway 中练习 41 并不断收到错误消息:
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
I am using python3 while the books uses python2, so I have made some changes. Here is the script:
我使用的是python3,而书籍使用的是python2,所以我做了一些更改。这是脚本:
#!/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")
What exactly am I doing wrong here? Thanks!
我到底做错了什么?谢谢!
采纳答案by Ashwini Chaudhary
urlopen()returns a bytes object, to perform string operations over it you should convert it to strfirst.
urlopen()返回一个字节对象,要对其执行字符串操作,您应该str先将其转换为。
for word in urlopen(WORD_URL).readlines():
WORDS.append(word.strip().decode('utf-8')) # utf-8 works in your case
To get the correct charset : How to download any(!) webpage with correct charset in python?
要获得正确的字符集: 如何在 python 中下载任何(!)具有正确字符集的网页?
回答by abarnert
In Python 3, the urlopenfunctionreturns an HTTPResponseobject, which acts like a binary file. So, when you do this:
在 Python 3 中,该urlopen函数返回一个HTTPResponse对象,其作用类似于二进制文件。所以,当你这样做时:
for word in urlopen(WORD_URL).readlines():
WORDS.append(word.strip())
… you end up with a bunch of bytesobjects instead of strobjects. So when you do this:
......你最终会得到一堆bytes对象而不是str对象。所以当你这样做时:
result = result.replace("###", word, 1)
… you end up trying to replace the string "###"within the string resultwith a bytesobject, instead of a str. Hence the error:
...你最终试图用一个对象替换字符串"###"中的字符串,而不是一个. 因此错误:resultbytesstr
TypeError: Can't convert 'bytes' object to str implicitly
The answer is to explicitly decode the words as soon as you get them. To do that, you have to figure out the right encoding from the HTTP headers. How do you do that?
答案是在获得单词后立即对其进行显式解码。为此,您必须从 HTTP 标头中找出正确的编码。你是怎样做的?
In this case, I read the headers, I can tell that it's ASCII, and it's obviously a static page, so:
在这种情况下,我阅读了标题,我可以看出它是 ASCII,而且它显然是一个静态页面,所以:
for word in urlopen(WORD_URL).readlines():
WORDS.append(word.strip().decode('ascii'))
But in real life, you usually need to write code that reads the headers and dynamically figures it out. Or, better, install a higher-level library like requests, which does that for you automatically.
但在现实生活中,您通常需要编写读取标头并动态计算出来的代码。或者,更好的是,安装一个更高级别的库,例如requests,它会自动为您执行此操作。
回答by rajkrish06
Explicitly convert byte type 'word' into string
显式将字节类型 'word' 转换为字符串
result = result.replace("###", sre(word), 1)
it should work
它应该工作

