我在“学习Python艰难之路”一书中做了ex49的练习。 我在nosetest中得到了AttributeError,而我可以通过python shell中的excute命令传递。 我在Ubuntu 15.10编码,python版本是3.4.3。 目录结构如下:
.:
bin docs ex49 lexicon.py parser.py readme setup.py tests
./bin:
./docs:
./ex49:
__init__.py
./tests:
ex49_test.py __init__.py
lexicon.py:
#!/usr/bin/env python
# encoding: utf-8
direction_base = ['north', 'south', 'west', 'east', 'down', 'up', 'left', 'right', 'back']
verb_base = ['go', 'kill', 'eat', 'open']
stop_base = ['the', 'in', 'of', 'it']
noun_base = ['door', 'bear', 'princess', 'carbinet']
def convert_number(s):
try:
return int(s)
except ValueError:
return None
def scan(strInput):
wordList = strInput.lower().split(' ')
resultSentence = []
for word in wordList:
if word in direction_base:
resultSentence.append(('direction', word))
elif word in verb_base:
resultSentence.append(('verb', word))
elif word in stop_base:
resultSentence.append(('stop', word))
elif word in noun_base:
resultSentence.append(('noun', word))
elif convert_number(word) is not None:
resultSentence.append(('number', int(word)))
else:
resultSentence.append(('error', word))
return resultSentence
parser.py:
#!/usr/bin/env python
# encoding: utf-8
class ParserError(Exception):
pass
class Sentence(object):
def __init__(self, subject, verb, number, object):
# remember we take ('noun','princess') tuples and convert them
self.subject = subject[1]
self.verb = verb[1]
self.number = number[1]
self.object = object[1]
def to_tuple(self):
return (self.subject, self.verb, self.number, self.object)
def peek(word_list):
if word_list:
word = word_list[0]
return word[0]
else:
return None
def match(word_list, expecting):
if word_list:
word = word_list.pop(0)
if word[0] == expecting:
return word
else:
return None
else:
return None
def skip(word_list, word_type):
while peek(word_list) == word_type:
match(word_list, word_type)
def parse_verb(word_list):
skip(word_list, 'stop')
if peek(word_list) == 'verb':
return match(word_list, 'verb')
else:
raise ParserError("Expected a verb next.")
def parse_object(word_list):
skip(word_list, 'stop')
next_item = peek(word_list)
if next_item == 'noun':
return match(word_list, 'noun')
elif next_item == 'direction':
return match(word_list, 'direction')
else:
raise ParserError("Expected a noun or direction next.")
def parse_number(word_list, number):
skip(word_list, 'stop')
if peek(word_list) == 'number':
return match(word_list, 'number')
else:
return ('number', 1)
def parse_subject(word_list, subj):
verb = parse_verb(word_list)
number = parse_number(word_list)
obj = parse_object(word_list)
return Sentence(subj, verb, number, obj)
def parse_sentence(word_list):
skip(word_list, 'stop')
start_item = peek(word_list)
if start_item == 'noun':
subj = match(word_list, 'noun')
return parse_subject(word_list, subj)
elif start_item == 'verb':
# assume the subject is the player then
return parse_subject(word_list, ('noun', 'player'))
else:
raise ParserError("Must start with subject, object, or verb not: %s" % start_item)
ex49_test.py:
#!/usr/bin/env python
# encoding: utf-8
from nose.tools import *
import lexicon
import parser
def test_sentence_obj():
s = parser.Sentence(('noun', 'bear'), ('verb', 'eat'), ('number', 1), ('noun', 'door'))
assert_equal(s.subject, 'bear')
assert_equal(s.verb, 'eat')
assert_equal(s.number, 1)
assert_equal(s.object, 'door')
assert_equal(s.to_tuple(), ('bear', 'eat', 1, 'door'))
def test_peek():
word_list = lexicon.scan('princess')
assert_equal(parser.peek(word_list), 'noun')
assert_equal(parser.peek(None), None)
def test_match():
word_list = lexicon.scan('princess')
assert_equal(parser.match(word_list, 'noun'), ('noun', 'princess'))
assert_equal(parser.match(word_list, 'stop'), None)
assert_equal(parser.match(None, 'noun'), None)
def test_skip():
word_list = lexicon.scan('bear eat door')
assert_equal(word_list, [('noun', 'bear'), ('verb', 'eat'), ('noun', 'door')])
parser.skip(word_list, 'noun')
assert_equal(word_list, [('verb', 'eat'), ('noun', 'door')])
def test_parse_verb():
word_list = lexicon.scan('it eat door')
assert_equal(parser.parse_verb(word_list), ('verb', 'eat'))
word_list = lexicon.scan('bear eat door')
assert_raise(parser.ParserError, parser.parse_verb, word_list)
def test_parse_object():
word_list = lexicon.scan('the door')
assert_equal(parser.parse_object(word_list), ('noun', 'door'))
word_list = lexicon.scan('the east')
assert_equal(parser.parse_object(word_list), ('direction', 'east'))
word_list = lexicon.scan('the it')
assert_raise(parser.ParserError, parser.parse_object, word_list)
def test_parse_subject():
word_list = lexicon.scan('eat door')
subj = ('noun', 'bear')
s = parser.parse_subject(word_list, subj)
assert_raise(s.to_tuple(), ('bear', 'eat', 1, 'door'))
def test_parse_sentence():
word_list = lexicon.scan('the bear eat door')
s = parser.parse_sentence(word_list)
assert_equal(s.to_tuple(), ('bear', 'eat', 1, 'door'))
word_list = lexicon.scan('in the door')
s = parser.parse_sentence(word_list)
assert_equal(s.to_tuple(), ('player', 'eat', 1, 'door'))
word_list = lexicon.scan('north eat door')
assert_equal(parser.ParserError, parser.parse_sentence, word_list)
def test_unknown_words():
word_list = lexicon.scan('xxx the xxx bear xxx eat xxx 5 xxx door xxx')
s = parser.parse_sentence(word_list)
assert_equal(s.to_tuple(), ('bear', 'eat', 1, 'door'))
def test_number():
word_list = lexicon.scan('xxx the xxx bear xxx eat xxx 5 xxx door xxx')
s = parser.parse_sentence(word_list)
assert_equal(s.to_tuple(), ('bear', 'eat', 5, 'door'))
执行错误:
~/Documents/python3/practice/ex49$ nosetests3 tests/
EEEEEEEEEE
======================================================================
ERROR: tests.ex49_test.test_sentence_obj
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 8, in test_sentence_obj
s = parser.Sentence(('noun', 'bear'), ('verb', 'eat'), ('number', 1), ('noun', 'door'))
AttributeError: 'module' object has no attribute 'Sentence'
======================================================================
ERROR: tests.ex49_test.test_peek
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 17, in test_peek
assert_equal(parser.peek(word_list), 'noun')
AttributeError: 'module' object has no attribute 'peek'
======================================================================
ERROR: tests.ex49_test.test_match
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 22, in test_match
assert_equal(parser.match(word_list, 'noun'), ('noun', 'princess'))
AttributeError: 'module' object has no attribute 'match'
======================================================================
ERROR: tests.ex49_test.test_skip
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 29, in test_skip
parser.skip(word_list, 'noun')
AttributeError: 'module' object has no attribute 'skip'
======================================================================
ERROR: tests.ex49_test.test_parse_verb
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 34, in test_parse_verb
assert_equal(parser.parse_verb(word_list), ('verb', 'eat'))
AttributeError: 'module' object has no attribute 'parse_verb'
======================================================================
ERROR: tests.ex49_test.test_parse_object
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 40, in test_parse_object
assert_equal(parser.parse_object(word_list), ('noun', 'door'))
AttributeError: 'module' object has no attribute 'parse_object'
======================================================================
ERROR: tests.ex49_test.test_parse_subject
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 49, in test_parse_subject
s = parser.parse_subject(word_list, subj)
AttributeError: 'module' object has no attribute 'parse_subject'
======================================================================
ERROR: tests.ex49_test.test_parse_sentence
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 54, in test_parse_sentence
s = parser.parse_sentence(word_list)
AttributeError: 'module' object has no attribute 'parse_sentence'
======================================================================
ERROR: tests.ex49_test.test_unknown_words
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 64, in test_unknown_words
s = parser.parse_sentence(word_list)
AttributeError: 'module' object has no attribute 'parse_sentence'
======================================================================
ERROR: tests.ex49_test.test_number
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/lib/python3/dist-packages/nose/case.py", line 198, in runTest
self.test(*self.arg)
File "/home/chungyi/Documents/python3/practice/ex49/tests/ex49_test.py", line 69, in test_number
s = parser.parse_sentence(word_list)
AttributeError: 'module' object has no attribute 'parse_sentence'
----------------------------------------------------------------------
Ran 10 tests in 0.007s
FAILED (errors=10)
答案 0 :(得分:0)
您的问题出在parser
模块命名中。不幸的是,python中有一个内置的parser
模块:尝试在任何文件夹中运行python并运行import parser
。现在检查parser.__file__
以查看它引用的实际模块:对我来说它指的是:
>>> import parser
>>> parser.__file__
'/usr/lib/python2.7/lib-dynload/parser.x86_64-linux-gnu.so'
所以你的ex49_test.py
选错了parser
这就是python试图告诉你的:AttributeError: 'module' object has no attribute 'match'
意味着在这个模块中没有match
方法。将解析器重命名为其他内容,看看生活是否变得更好。