字段之间无关的字典共享?

Zac*_*ach 2 python class nltk data-structures

以下代码应该创建频率分布的新(修改)版本(nltk.FreqDist).两个变量应该是相同的长度.

当创建单个WebText实例时,它可以正常工作.但是当创建多个WebText实例时,新变量似乎被所有对象共享.

例如:

import nltk
from operator import itemgetter

class WebText:

    freq_dist_weighted = {}

    def __init__(self, text):
        tokens = nltk.wordpunct_tokenize(text) #tokenize
        word_count = len(tokens)
        freq_dist = nltk.FreqDist(tokens)


        for word,frequency in freq_dist.iteritems():
            self.freq_dist_weighted[word] = frequency/word_count*frequency
        print len(freq_dist), len(self.freq_dist_weighted)

text1 = WebText("this is a test")
text2 = WebText("this is another test")
text3 = WebText("a final sentence")
Run Code Online (Sandbox Code Playgroud)

结果是

4 4
4 5
3 7
Run Code Online (Sandbox Code Playgroud)

这是不正确的.由于我只是转置和修改值,因此每列中应该有相同的数字.如果我在循环之前重置freq_dist_weighted,它可以正常工作:

import nltk
from operator import itemgetter

class WebText:

    freq_dist_weighted = {} 

    def __init__(self, text):
        tokens = nltk.wordpunct_tokenize(text) #tokenize
        word_count = len(tokens)
        freq_dist = nltk.FreqDist(tokens)
        self.freq_dist_weighted = {}

        for word,frequency in freq_dist.iteritems():
            self.freq_dist_weighted[word] = frequency/word_count*frequency
        print len(freq_dist), len(self.freq_dist_weighted)

text1 = WebText("this is a test")
text2 = WebText("this is another test")
text3 = WebText("a final sentence")
Run Code Online (Sandbox Code Playgroud)

结果(正确):

4 4
4 4
3 3
Run Code Online (Sandbox Code Playgroud)

这对我来说没有意义.

我不明白为什么我必须重置它,因为它在对象中是孤立的.难道我做错了什么?

Ign*_*ams 9

你的评论是完全错误的.类范围中的对象仅在创建类时初始化; 如果您希望每个实例使用不同的对象,则需要将其移动到初始化程序中.

class WebText:
    def __init__(self, text):
        self.freq_dist_weighted = {} #### RESET the dictionary HERE ####
         ...
Run Code Online (Sandbox Code Playgroud)


kin*_*all 6

您的freq_dist_weighted字典是类属性,而不是实例属性.因此,它在类的所有实例之间共享.(self.freq_dist_weighted仍然引用类属性;因为该名称没有特定于实例的属性,所以Python会回到查看该类.)

要使其成为实例属性,请在类的__init__()方法中设置它.

def __init__(self, text):
    self.freq_dist_weighted = {}
    ...
Run Code Online (Sandbox Code Playgroud)