Более эффективный вызов метода в Python

Я новичок, работаю над Learn Python the Hard Way.

Целью этого упражнения является написание сканера слов, который проходит носовые тесты при выполнении предоставленного модульного теста.

При выполнении носовых тестов в следующем предоставленном модульном тесте я получил эту ошибку:

`TypeError: несвязанный метод scan() должен вызываться с экземпляром словаря в качестве первого аргумента (вместо этого получен экземпляр str)

Тест, предоставленный уроком

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)])

После некоторого расследования я нашел здесь пользователя, который работает над тем же упражнением:

nosetests, python

переменные Python, классы

В ответе предлагалось создать (создать?) метод внутри модульного теста. Итак, я сделал следующую модификацию и записал свой класс в файл ex48.py, и он проходит носовые тесты.

Измененный тест

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

Я не уверен, что модульный тест должен был быть изменен. Я нашел подсказку о «непосредственном создании объекта» здесь:

Python: вызов метода "напрямую" создает экземпляр объекта?< /а>

Но не уверен, что это применимо. Можно ли заставить сканер создавать экземпляр самого себя или предоставленный модульный тест является «вопросом» с подвохом и должен быть изменен?


person Steve Narrow    schedule 30.07.2011    source источник


Ответы (2)


Вы должны оставить тест таким, каким он был, и использовать декоратор @staticmethod в методе сканирования. Таким образом, вы сможете вызывать метод непосредственно из класса без необходимости создавать для этого экземпляр объекта.

class lexicon(object):

   @staticmethod
   def scan(data):
      #do the stuff here
person Cédric Julien    schedule 30.07.2011
comment
Это сработало с небольшой модификацией: def scan(data): Большое спасибо. :) - person Steve Narrow; 31.07.2011

В онлайн-версии Learn Python The Hard Way есть:

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 с функцией сканирования для тестирования.

И это пишется как создание экземпляра (например, я создаю экземпляр этого класса).

person user500198    schedule 30.07.2011
comment
Ах да, мой плохой там, я не скопипастил оригинал, а изменил и удалил лишние строки. Спасибо. - person Steve Narrow; 31.07.2011
comment
И я тоже попробовал это, используя файл lexicon.py и изменив импорт. Работает также. Мучас. - person Steve Narrow; 31.07.2011