首页 > 解决方案 > Python def 中关闭文件的 I/O 操作

问题描述

我知道这是重复的,但我已经查看了答案,但没有一个能解释为什么我会收到 ValueError: I/O operation on closed file in this specific python 2.7 function in this write here。

将其分离为独立的 sciptlet 时没有错误:

import hashlib
import sys

sha256_hash = hashlib.sha256()

filename = 'result.txt'

with open(filename,"rb") as f:
# Read and update hash string value in blocks of 4K
    for byte_block in iter(lambda: f.read(4096),b""):
        sha256_hash.update(byte_block)
    print(sha256_hash.hexdigest())
f.close()

但是当我把它放到一个定义的函数中时,我在打印函数上得到一个 ValueError 。

def sha256hashcheck():
    with open( 'goldresult.txt' ,"rb") as f:
        # Read and update hash string value in blocks of 4K
        for byte_block in iter(lambda: f.read(4096),b""):
            sha256_hash.update(byte_block)
        print(sha256_hash.hexdigest())
    f.close()

sha256hashcheck()

所有其他定义的函数在退出函数之前运行 close() 方法,另外我在没有函数调用的一侧创建了一个测试文件并将其用作 def 中的打开,我仍然得到 ValueError 异常

  File "parse-o365-ip-addrs.py", line 61, in sha256hashcheck
    print(sha256_hash.hexdigest())
ValueError: I/O operation on closed file

任何指示或建议?


这是我的整个脚本 .. 是的,我是 python 新手 .. :)

# Initial code - https://gist.github.com/cdodd/7679fb9c5f2a2e4700c7a9c7a53e2a19 (cdodd)
import xmltodict
from socket import inet_ntoa
from struct import pack
import sys
import urllib
import hashlib

# Read from URL
data = urllib.urlopen('https://support.content.office.net/en-us/static/O365IPAddresses.xml').read()
doc = xmltodict.parse(data)
# Read from local file
# doc = xmltodict.parse(open('/path/to/file.xml').read())

# set your variables
subnettestVar = 'test.txt'
subnetresultVar = 'result.txt'
subnetgoldVar = 'goldresult.txt'
sha256_hash = hashlib.sha256()

#define your functions or classes

def calcDottedNetmask(mask):
    bits = 0xffffffff ^ (1 << 32 - mask) - 1
    return inet_ntoa(pack('>I', bits))

# Work to be done, if x['@name'] still shells exception (KeyError) on 'OneNote' because OneNote has no IPv4 address
# Still need to work out either .get (dict) or try - exception errorhandling for that issue 
def getsubnets():
    sys.stdout = open( subnettestVar , 'w')
    for x in doc['products']['product']:
        if x['@name'] in ['o365', 'Identity', 'Planner', 'ProPlus', 'Yammer', 'Teams', 'SPO', 'LYO', 'WAC']:
            for y in x['addresslist']:
                if y['@type'] == 'IPv4':
                    for ip in y['address']:
                        if '/' not in ip:
                            ip, dot_mask = (ip, '255.255.255.255')
                        else:
                            ip, cidr_mask = ip.split('/')
                            dot_mask = calcDottedNetmask(int(cidr_mask))
                        print 'network-object ' + ip + ' ' + dot_mask
                    print
    sys.stdout.close()

def removeblanklines():
    with open( subnettestVar ,'r+') as file, open( subnetresultVar ,"w") as outfile:
        for i in file.readlines():
            if not i.strip():
                continue
            if i:   
                outfile.write(i)
    file.close()
    outfile.close()

def sha256hashcheck():
    with open( 'goldresult.txt' ,"rb") as f:
        # Read and update hash string value in blocks of 4K
        for byte_block in iter(lambda: f.read(4096),b""):
            sha256_hash.update(byte_block)
        print(sha256_hash.hexdigest())
    f.close()

#Run your full program with all functions, classes and variables

getsubnets()
removeblanklines()
sha256hashcheck()

标签: pythonpython-2.7file-io

解决方案


所有,感谢您的指点,ShadowRanger 一针见血——我很愚蠢并调用了 sys.stdout.close() 。

创建了一个适当的“with”“as”来打开文件并正确调用文件打开,只需要对打印行大惊小怪并调用 filename.write 而不是依赖于控制台而不是文件特定的打印语句。

如果您愿意,请随时索取答案...


推荐阅读