嗨我想在列表中保存包含“CREATE TABLE”的所有行的位置 a)有更好,更正确的方法吗? (我是python的新手) b)为什么告诉被用于迭代器?我认为它是一个读取方法(或等价物),因此只是告诉位置不应该损害文件迭代过程。
所以我有以下课程:
class SQLParser(object):
def __init__(self,filename):
self.file = open(filename,'r')
self.createTablePositions=[]
self.insertIntoPositions=[]
def findCreateTable(self):
for line in self.file:
if line.find("CREATE TABLE") is 0:
print(line)
self.createTablePositions.append(self.file.tell())
sqlhandler = SQLParser("sql.sql")
sqlhandler.findCreateTable()
print(sqlhandler.createTablePositions)
产生以下错误:“Traceback(最近一次调用最后一次): 文件“C:/Users/user/PycharmProjects/sqlparser/sqlparser.py”,第18行,in sqlhandler.findCreateTable() 在findCreateTable中的文件“C:/Users/user/PycharmProjects/sqlparser/sqlparser.py”,第12行 curPos = self.file.tell() OSError:通过next()调用“
告知位置被禁用我搜索了网络和stackoverflow,但我找不到直接解决我的问题。 - 目前解决方案就像重写next()方法一样超出了我的知识,我怀疑这个练习的目标是什么。
请您的建议高度评价!
答案 0 :(得分:0)
首先,你永远不会关闭文件,这不好。
错误的产生主要是由于tell()
方法的内部行为。通过for line in file
迭代文件,您不断调用内部操作next()
,这会混淆tell()
方法的工作方式。通常最好使用特定方法从文件中读取数据:readline()
或readlines()
。除非您知道完全您正在做什么,否则迭代由OS(文件系统)控制的对象可能会由于访问方法(有时)或其他方式的冲突而导致错误。
同样file.tell()
方法返回光标的位置而不是您所在的行。因此,如果您说您正在阅读包含20个字符的第一行,则在使用file.readline()
后,方法file.tell()
将返回22
(字符数加上结束字符或其他字符)
而不是你在做什么,我建议以不同的方式思考它。
class SQLParser(object):
"""
Parses a SQL file.
"""
def __init__(self,filename):
self.createTablePositions= self.findCreateTable(filename)
self.insertIntoPositions=[]
def findCreateTable(self, filename):
temp = []
with open(filename, 'r') as file:
# with operator closes the file upon exit of block
fileNum = 0
for line in file.readlines():
if "CREATE TABLE" in line:
print(line)
temp.append(fileNum)
fileNum += 1
return temp
sqlhandler = SQLParser("sql.sql")
print(sqlhandler.createTablePositions)
因此,现在,您将在初始化类对象时解析文件。
然后,您可以继续为insertIntoPosition
的其他方法执行类似的操作。
答案 1 :(得分:0)
如果你的SQL文件过大,根据this answer有两种解决方法:
file.readline()
而不是 next()
with open(path, mode) as file:
while True:
line = file.readline()
if not line:
break
file.tell()
offset += len(line)
而不是 file.tell()
offset = 0
with open(path, mode) as file:
for line in file:
offset += len(line)