简体   繁体   English

未找到Python方法,但在类中定义

[英]Python method not found, but defined in class

I'm teaching myself (probably my first mistake) classes and methods by converting a sentiment analysis script to use them. 我通过转换情绪分析脚本来使用它们来教我自己(可能是我的第一个错误)类和方法。

I thought I had all of the methods in place, but I keep getting 以为我已经掌握了所有方法,但我一直在努力

global name 'get_bigram_word_feats' is not defined

I'm sure I'd be getting an error for get_word_feats , too, if it got that far. 我确定我也会收到get_word_feats的错误,如果它到那么远的话。

I'm banging my head against this one big-time. 我正在撞击这个伟大的时间。 I tried removing staticmethod and adding self. 我尝试删除staticmethod并添加self。 What am I doing wrong? 我究竟做错了什么?

Here's my code: 这是我的代码:

def word_feats(words):
    return dict([(word, True) for word in words])


class SentClassifier:

    def __init__(self, name, location):
        self.name = name
        self.location = location
        self.fullpath = location + "/" + name

    def doesexist(self):
        return os.path.isfile(self.fullpath)

    def save_classifier(self):
        rf = open(self.fullpath, 'wb')
        pickle.dump(self.fullpath, rf)
        rf.close()

    def load_classifier(self):
        sf = open(self.fullpath, 'rb')
        sclassifier = pickle.load(sf)
        sf.close()
        return sclassifier


class Training:

    def __init__(self, neg, pos):
        self.neg = neg
        self.pos = pos
        self.negids = open(self.neg, 'rb').read().splitlines(True)
        self.posids = open(self.pos, 'rb').read().splitlines(True)
        self.exclude = set(string.punctuation)
        self.exclude = self.exclude, '...'
        self.swords = stopwords.words('english')

    def tokens(self, words):
        words = [w for w in nltk.word_tokenize(words) if w not in self.exclude and len(w) > 1
            and w not in self.swords and wordnet.synsets(w)]
        return words

    def idlist(self, words):
        thisidlist = [self.tokens(tf) for tf in words]
        return thisidlist

    @staticmethod
    def get_word_feats(words):
        return dict([(word, True) for word in words])

    @staticmethod
    def get_bigram_word_feats(twords, score_fn=BigramAssocMeasures.chi_sq, tn=200):
        words = [w for w in twords]
        bigram_finder = BigramCollocationFinder.from_words(words)
        bigrams = bigram_finder.nbest(score_fn, tn)
        return dict([(ngram, True) for ngram in itertools.chain(words, bigrams)])

    @staticmethod
    def label_feats(thelist, label):
        return [(get_word_feats(lf), label) for lf in thelist]

    @staticmethod
    def label_grams(thelist, label):
        return [(get_bigram_word_feats(gf), label) for gf in thelist()]

    @staticmethod
    def combinegrams(grams, feats):
        for g in grams():
            feats.append(g)
        return feats

    def negidlist(self):
        return self.idlist(self.negids)

    def posidlist(self):
        return self.idlist(self.posids)

    def posgrams(self):
        return self.label_grams(self.posidlist, 'pos')

    def neggrams(self):
        return self.label_grams(self.negidlist, 'neg')

    def negwords(self):
        return self.label_feats(self.negidlist, 'neg')

    def poswords(self):
        return self.label_feats(self.posidlist, 'pos')

    def negfeats(self):
        return self.combinegrams(self.neggrams, self.negwords)

    def posfeats(self):
        return self.combinegrams(self.posgrams, self.poswords)

starttime = time.time()

myclassifier = SentClassifier("sentanalyzer.pickle", "classifiers")

if myclassifier.doesexist() is False:
    print "training new classifier"
    trainset = Training('data/neg.txt', 'data/pos.txt')
    negfeats = trainset.negfeats()
    posfeats = trainset.posfeats()
    negcutoff = len(negfeats) * 8 / 10
    poscutoff = len(posfeats) * 8 / 10

    trainfeats = negfeats[:negcutoff] + posfeats[:poscutoff]
    testfeats = negfeats[negcutoff:] + posfeats[poscutoff:]
    print 'train on %d instances, test on %d instances' % (len(trainfeats), len(testfeats))

    classifier = NaiveBayesClassifier.train(trainfeats)
    print 'accuracy:', nltk.classify.util.accuracy(classifier, testfeats)
    myclassifier.save_classifier()

else:
    print "using existing classifier"
    classifier = myclassifier.load_classifier()

classifier.show_most_informative_features(20)
mystr = "16 steps to an irresistible sales pitch, via @vladblagi: slidesha.re/1bVV7OS"
myfeat = word_feats(nltk.word_tokenize(mystr))
print classifier.classify(myfeat)

probd = classifier.prob_classify(myfeat)

print probd.prob('neg')
print probd.prob('pos')

donetime = time.time() - starttime

print donetime

All the information you need is in the exception message: 您需要的所有信息都在异常消息中:

global name 'get_bigram_word_feats' is not defined 未定义全局名称“get_bigram_word_feats”

(my emphasis) (我的重点)

Python doesn't understand that you want to access that method from the class, since you did not specify the class name as part of the method invocation. Python不理解您要从类中访问该方法,因为您没有将类名指定为方法调用的一部分。 As such, it is looking for the function in the global namespace and failed to find it. 因此,它正在全局命名空间中查找该函数,但未能找到它。

If you recall from calling instance methods, you need to prefix the methods with self. 如果从调用实例方法中回忆起来,则需要在方法前加上self. to make the Python interpreter look in the right place, and this also holds for static methods though you do not specify self. 使Python解释器看起来正确,虽然你没有指定self. ,但这也适用于静态方法self. , instead you specify the class name. 而是指定类名。

So to fix this, prefix the call to the method with the class name: 因此,要解决此问题,请使用类名称对方法的调用作为前缀:

return [(Training.get_bigram_word_feats(gf), label) for gf in thelist()]
         ^---+---^
             |
             +-- you need this part

global name 'get_bigram_word_feats' is not defined 未定义全局名称“get_bigram_word_feats”

Your call should look like this (note the class name being used here): 你的电话应该是这样的(请注意这里使用的班级名称):

@staticmethod
def label_grams(thelist, label):
    return [(Training.get_bigram_word_feats(gf), label) for gf in thelist()]

In general, for static methods, use the class name. 通常,对于静态方法,请使用类名。


I tried removing staticmethod and adding self. 我尝试删除staticmethod并添加self。 What am I doing wrong? 我究竟做错了什么?

In that case, you'd use self.funcName(..) . 在这种情况下,您将使用self.funcName(..) Something like below: 如下所示:

def label_grams(self, thelist, label):
    return [(self.get_bigram_word_feats(gf), label) for gf in thelist()]

Good news: the fix is simple. 好消息:修复很简单。 Call it this way: Training.get_bigram_word_feats(...) . 这样称呼: Training.get_bigram_word_feats(...)

Eg, 例如,

@staticmethod
def label_grams(thelist, label):
    return [(Training.get_bigram_word_feats(gf), label) for gf in thelist()]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM