Python代码报错:'str'无decode属性及语法错误求解
解决日语WordNet Python代码的两个报错
问题描述
运行基于日语WordNet的Python代码时遇到以下两个错误:
- 执行
words = getWords(sys.argv[1].decode(sys.stdin.encoding))时,触发AttributeError: 'str' object has no attribute 'decode' - 移除
decode调用后,出现SyntaxError: invalid syntax,错误指向if words:行
错误1:AttributeError: 'str' object has no attribute 'decode'
原因
Python 3中,sys.argv传入的命令行参数已经是Unicode字符串(str类型),而decode()是Python 2中bytes类型的方法,Python 3的str对象没有这个属性,因此调用会报错。
解决方法
直接删除.decode(sys.stdin.encoding),修改为:
words = getWords(sys.argv[1])
错误2:SyntaxError: invalid syntax
原因
代码使用了Python 2的语法特性,在Python 3环境下无法解析:
- Python 2的
print >>sys.stderr, "(nothing found)"是语句写法,Python 3中print是内置函数,必须用括号包裹参数并指定file参数输出到标准错误流; len(sys.argv)>=3 and sys.argv[2] or 'hypo'属于不规范写法,容易引发逻辑歧义。
解决方法
- 将标准错误输出的print语句修改为Python 3格式:
# 原Python 2写法 print >>sys.stderr, "(nothing found)" # 修改为Python 3写法 print("(nothing found)", file=sys.stderr) - 用三元表达式替换
and/or的条件赋值写法,提升可读性:# 原写法 link = len(sys.argv)>=3 and sys.argv[2] or 'hypo' lang = len(sys.argv)==4 and sys.argv[3] or 'jpn' # 修改为三元表达式 link = sys.argv[2] if len(sys.argv) >= 3 else 'hypo' lang = sys.argv[3] if len(sys.argv) == 4 else 'jpn'
完整修正后的代码
#!/usr/bin/env python3 # encoding: utf-8 import sys import sqlite3 from collections import namedtuple conn = sqlite3.connect("wnjpn.db") Word = namedtuple('Word', 'wordid lang lemma pron pos') def getWords(lemma): cur = conn.execute("select * from word where lemma=?", (lemma,)) return [Word(*row) for row in cur] def getWord(wordid): cur = conn.execute("select * from word where wordid=?", (wordid,)) return Word(*cur.fetchone()) Sense = namedtuple('Sense', 'synset wordid lang rank lexid freq src') def getSenses(word): cur = conn.execute("select * from sense where wordid=?", (word.wordid,)) return [Sense(*row) for row in cur] def getSense(synset, lang='jpn'): cur = conn.execute("select * from sense where synset=? and lang=?", (synset, lang)) row = cur.fetchone() return Sense(*row) if row else None Synset = namedtuple('Synset', 'synset pos name src') def getSynset(synset): cur = conn.execute("select * from synset where synset=?", (synset,)) return Synset(*cur.fetchone()) SynLink = namedtuple('SynLink', 'synset1 synset2 link src') def getSynLinks(sense, link): cur = conn.execute("select * from synlink where synset1=? and link=?", (sense.synset, link)) return [SynLink(*row) for row in cur] def getSynLinksRecursive(senses, link, lang='jpn', _depth=0): for sense in senses: synLinks = getSynLinks(sense, link) if synLinks: print(''.join([' '*2*_depth, getWord(sense.wordid).lemma, ' ', getSynset(sense.synset).name])) _senses = [] for synLink in synLinks: sense = getSense(synLink.synset2, lang) if sense: _senses.append(sense) getSynLinksRecursive(_senses, link, lang, _depth+1) def getWordsFromSynset(synset, lang): cur = conn.execute("select word.* from sense, word where synset=? and word.lang=? and sense.wordid = word.wordid;", (synset, lang)) return [Word(*row) for row in cur] def getWordsFromSenses(sense, lang): for s in sense: print(getSynset(s.synset).name) syns = getWordsFromSynset(s.synset, lang) for sy in syns: print(' ' + sy.lemma) if __name__ == '__main__': if len(sys.argv) >= 3: words = getWords(sys.argv[1]) if words: for w in words: sense = getSenses(w) link = sys.argv[2] if len(sys.argv) >= 3 else 'hypo' lang = sys.argv[3] if len(sys.argv) == 4 else 'jpn' if link == 'syns': getWordsFromSenses(sense, lang) else: getSynLinksRecursive(sense, link, lang) else: print("(nothing found)", file=sys.stderr) else: print("usage: python jpWordnet.py ピラミッド syns")
内容的提问来源于stack exchange,提问作者jms
相关产品推荐
相关产品推荐

