更高效地调用Python中的方法
我是一名新手,正在学习《Learn Python the Hard Way》这本书。
这个练习的目的是写一个单词扫描器,能够通过提供的单元测试的nosetests。
在运行nosetests时,我遇到了一个错误:
`TypeError: unbound method scan() must be called with lexicon instance as first argument (got str instance instead)`
提供的测试
from nose.tools import *
from ex48 import lexicon
def test_directions():
assert_equal(lex.scan("north"), [('direction', 'north')])
result = lex.scan("north south east")
assert_equal(result, [('direction', 'north'),
('direction', 'south'),
('direction', 'east)])
经过一些调查,我发现这里有个用户也在做同样的练习:
那里的回答建议在单元测试中实例化(也就是创建一个对象)这个方法。所以我做了以下修改,并在文件ex48.py中写了我的类,结果通过了nosetests。
修改后的测试
from nose.tools import *
from ex48 import lexicon
def test_directions():
lex = lexicon("north")
assert_equal(lex.scan("north"), [('direction', 'north')])
lex = lexicon("north south east")
result = lex.scan("north south east")
assert_equal(result, [('direction', 'north'),
('direction', 'south'),
('direction', 'east')])
ex48.py - 扫描器
class lexicon(object):
def __init__(self, data):
#nosetests fails me if I don't put in some dummy
# __init__ function with a dummy line, not sure why.
self.direction = data
def scan(self, data):
split_data = data.split()
directions = ['north', 'south', 'east', 'west']
data_reply = []
#for loop for the length of the list
for split_data_item in split_data:
#If data is in the directions list
if split_data_item in directions:
#Add [('direction', data)] to a dict
data_reply.append(('direction', split_data_item))
#Return the list
return data_reply
我不确定这个单元测试是否应该被修改。我在这里找到了一些关于“直接实例化一个对象”的线索:
但我不确定这是否适用。扫描器能否自己实例化,还是说提供的单元测试是个“陷阱”问题,必须被修改?
2 个回答
4
在《艰难学Python》的在线版本中,他们提到:
def test_directions():
assert_equal(lexicon.scan("north"), [('direction', 'north')])
result = lexicon.scan("north south east")
assert_equal(result, [('direction', 'north'),
('direction', 'south'),
('direction', 'east')])
对于测试来说,这意味着你不需要一个词汇类,而是需要一个包含扫描功能的lexicon.py文件来进行测试。
而且这里的“instantiating”是指我正在创建这个类的一个实例。
2
你应该保持测试的原样,然后在扫描方法上加一个 @staticmethod
装饰器。这样的话,你就可以直接从类里调用这个方法,而不需要先创建一个对象。
class lexicon(object):
@staticmethod
def scan(data):
#do the stuff here