0

I'm trying to test the following simple object:

class WebCorpus(object):
    def __init__(self):
        _index = {}
        _graph = {}
        _ranks = {}
        _corpusChanged = False

    def lookup(self, keyword):
        if keyword in _index:
            return _index[keyword]
        return None
# (some irrelevant code)

With:

from WebCorpus import WebCorpus

def test_engine():
    print "Testing..."
    content = """This is a sample <a href="http://www.example.com">webpage</a> with 
    <a href="http://www.go.to">two links</a> that lead nowhere special."""
    outlinks = ["http://www.example.com", "http://www.go.to"]

    corpus = WebCorpus()
    assert corpus.lookup("anything") == None
#(some more code)
test_engine()

But it gives me an error: NameError: global name '_index' is not defined. I don't understand this, _index is clearly defined in the __init__ !? What is my mistake here? Help appreciated.

2 Answers 2

4

In order to set class variables in the class method, you should use self:

class WebCorpus(object):
    def __init__(self):
        self._index = {}
        self._graph = {}
        self._ranks = {}
        self._corpusChanged = False

    def lookup(self, keyword):
        if keyword in self._index:
            return self._index[keyword]
        return None

Or, you can simplify the code and set variables like this (I've also simplified lookup method):

class WebCorpus(object):
    _index = {}
    _graph = {}
    _ranks = {}
    _corpusChanged = False

    def lookup(self, keyword):
        return self._index.get(keyword)

Note, the second example is not equivalent to the first one, because class-level variables are used, see comments below.

Sign up to request clarification or add additional context in comments.

5 Comments

The two example are not equivalent, in the second case, all instance of WebCorpus will share the _index, _graph, and _ranks attributes as they are class attributes and not instance attributes.
Agreed, but, keeping in mind that __init__.py doesn't accept any arguments, I think, this is what @ŞükrüHasdemir really wanted. Thank you.
Does that mean that once _index, for example, is set using one instance of WebCorpus, it will be the same for all instances @Sylvain?
@ŞükrüHasdemir: No, if you do corpus = WebCorpus() using the second implementation, then corpus._index = {"key": "value"} will override the dictionary for that specific instance. However, if you do c1, c2 = WebCorpus(), WebCorpus(), then c1._index["key"] = "value" will also change the content of c2._index (since they refer to the same object).
Yes, _index will be shared between instances.
2

What's happening here is that it's defining _index but then losing it after the __init__ is run. You should append self to everything, so it's self._index, etc. This goes for the entire class, not just in the __init__.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.