为什么fsize变量被全局清除?

时间:2016-01-03 16:44:24

标签: python python-2.7

我正在尝试计算python中文件的shannon熵。

所以,我编写了以下代码来实现这一目标。 但它并没有像预期的那样发挥作用。

我认为一切正确,但fsize变量已被清除。

我不明白为什么,因为它具有全球范围。

你能举手或解释吗?

由于

from __future__ import division
import sys
import os
import math


def get_chunks(file_size, chunk_size = 4096):

    chunk_start = 0

    while chunk_start + chunk_size < file_size:
        yield(chunk_start, chunk_size)
        chunk_start += chunk_size

    final_chunk_size = file_size - chunk_start
    yield(chunk_start, final_chunk_size)


def read_file_chunked(file_path):

    file_size = os.path.getsize(file_path)
    fsize = file_size # <------------------------------this var
    print('File size: {}'.format(file_size))

    with open(file_path,'rb') as file_:

        progress = 0

        for chunk_start, chunk_size in get_chunks(file_size):

            file_chunk = file_.read(chunk_size)

            # byte count
            for b in file_chunk:
                freqs[ord(b)]+=1

            progress += len(file_chunk)
            print '{0} of {1} bytes read ({2}%)'.format( progress, file_size, int(progress / file_size * 100))

        #calculate the frequency of each byte
        for idx, f in enumerate(freqs):
            freqs[idx] = float(f / file_size)
        print



freqs = [0] * 256
fsize = 0 #<------------------ this var


if len(sys.argv) != 2:
    print "Usage entropy [file]"
    sys.exit()

if __name__ == '__main__':

    read_file_chunked(sys.argv[1])

    # print byte frequencies
    for idx,f in enumerate(freqs):
        print hex(idx),f

    # calculate Shannon entropy
    ent = 0.0    
    for f in freqs:
        if f > 0:
            ent += f * math.log(f,2)
    ent = -ent

    print 'Shannon entropy ( min bits per byte-character )'
    print ent
    print
    print 'Min possible file size assuming max compression efficiency'
    print (ent * fsize), ' in bits' #------------------- here fsize is 0
    print (ent * fsize) / 8, ' in bytes' #-------------- here fsize is 0

2 个答案:

答案 0 :(得分:2)

fsize中分配给read_file_chunked会创建一个新的局部变量,该函数在函数返回时被删除。为了分配全局变量fsize,请明确声明它:

def read_file_chunked(file_path):
    global fsize
    file_size = os.path.getsize(file_path)
    fsize = file_size # <------------------------------this var

或者,让read_file_chunked返回文件大小。

答案 1 :(得分:2)

read_file_chunked函数中,您要在函数范围内创建新变量fsize,根本不需要修改全局变量。请考虑以下演示:

>>> x = 0
>>> def foo():
...     x = 1
... 
>>> foo()
>>> x
0

使用global关键字使您的代码按照您的意图运行所缺少的是:

>>> x = 0
>>> def foo():
...     global x
...     x = 1
... 
>>> foo()
>>> x
1

话虽如此,我质疑你对全局变量的使用。为什么不从你的职能中return fsize