Maya/Python-在文本文件中循环(某些行除外)的函数

Maya/Python-在文本文件中循环(某些行除外)的函数,python,maya,Python,Maya,我在这里和那里找到了一些答案,但我无法找到构建我想要的东西的确切方法。如果你能帮忙的话,提前谢谢你 我有多个文本文件,都是以相同的方式构建的,但每个文件中的信息不同。我想循环遍历每个文件,并逐行返回其中的信息。另一方面,我有一些布尔值,它们定义了是否必须跳过文件中的某一行。例如:“如果boolean1为true且对应文件中的lineincorrespondingfile=40,则跳过该行,否则,请阅读该行,但跳过第36行和第37行” 问题是我不知道如何继续,因为函数知道哪个文件被打开,哪个行被读

我在这里和那里找到了一些答案,但我无法找到构建我想要的东西的确切方法。如果你能帮忙的话,提前谢谢你

我有多个文本文件,都是以相同的方式构建的,但每个文件中的信息不同。我想循环遍历每个文件,并逐行返回其中的信息。另一方面,我有一些布尔值,它们定义了是否必须跳过文件中的某一行。例如:“如果boolean1为true且对应文件中的lineincorrespondingfile=40,则跳过该行,否则,请阅读该行,但跳过第36行和第37行”

问题是我不知道如何继续,因为函数知道哪个文件被打开,哪个行被读取,以及是否必须跳过它。知道我需要在函数结束时独立返回每一行

这是我到目前为止的代码:

def locatorsDatas (self):

    preset = cmds.optionMenu ("presetMenu", q = 1, v = 1)
    rawFile = presetsDir + preset.lower() + ".txt"

    with open(rawFile) as file:
        file.seek (0)
        for lineNum, line in enumerate(file, start = 1):
            if lineNum > 8 : # Skip header
                locator = eval (line)
                locName = locator[0]
                xVal = locator[1]
                yVal = locator[2]
                zVal = locator[3]
                locScale = locator[4]
                locColor = locator[5]
                if locator == "":
                    break

                return (locName, xVal, yVal, zVal, locScale, locColor)
我不知道应该向函数中传递什么值以使其跳过我想要的行,因为我知道我不能直接将其写入函数中,因为每个文件不会在同一行中断。 哦,它只返回文件的一行,而不是单独返回每一行


希望您能清楚地告诉我,并能帮助我,再次感谢。

我发现您的代码存在许多问题

首先,您总是从第8行返回数据,而从不返回任何其他数据。如果要从文件中提取多个值,则可能需要使用
yield
语句而不是
return
,使函数成为生成器。然后,调用代码可以通过
for
循环访问数据,或者将生成器传递到
list
或接受任何iterable的另一个函数

def locatorsDatas(self):
    # ...
    lineNum, line in enumerate(file, start=1):
        # ...
        yield results
如果不能使用生成器,但需要函数返回连续的行,则需要将文件迭代器(或者可能是围绕它的
枚举
迭代器)保存在函数范围之外的某个位置。这意味着您无需在每次调用函数时重新打开该文件。你可以这样做:

def __init__(self):
    preset = cmds.optionMenu ("presetMenu", q = 1, v = 1)
    rawFile = presetsDir + preset.lower() + ".txt"
    self.preset_file_enumerator = enumerate(open(rawFile)) # save the iterator on self

def locatorsDatas(self):
    try:
        lineNum, line = next(self.preset_file_enumerator) # get a value from the iterator
        # do your processing
        return results
    except StopIteration:
        # do whatever is appropriate when there's no more data in the file here
        raise ValueError("no more data") # such as raising an exception
我看到的下一个问题是如何处理每一行以获得独立的数据片段。您使用的是
eval
,如果您正在处理的数据被稍微委托,这是一个非常糟糕的主意。这是因为
eval
将其参数解释为Python代码。它可以做任何事情,包括从硬盘删除文件!更安全的版本是
ast.literal\u eval
,它只允许字符串包含Python文本(包括列表、字典和集合,但不允许变量查找、函数调用或其他更复杂的代码)

你也有一个错误检查,我不认为它会做你想做的。
if locator==”
测试可能放置得太晚,以避免前面从
eval
'd行提取数据的行出现错误。运行的
break
语句将导致函数退出,不再返回任何内容。如果您只想跳过空行,则应将检查放在循环的顶部,并使用
继续
,而不是
中断

现在我们终于可以开始讨论你在问题标题中提出的问题了。如果要基于各种标志跳过某些行,只需在循环时检查这些标志,然后执行
continue
跳过不想读取的行。我不完全理解您所问的关于如何传递标志的问题,但假设您可以将它们作为参数提供,下面是代码外观的示意图:

def locatorsDatas(self, skip_40=False, skip_50=True):
    # open file, ...
    for lineNum, line in enumerate(file, start = 1):
        if  (not line or
             lineNum < 8 or
             skip_40 and lineNum == 40 or
             skip_50 and lineNum == 50):
            continue
        # parse the line
        yield result
def locatorsDatas(self,skip_40=False,skip_50=True):
#打开文件。。。
对于lineNum,枚举(文件,开始=1)中的行:
如果(不是线或
lineNum<8或
跳过_40且lineNum==40或
跳过_50和lineNum==50):
持续
#解析行
产量结果

显然,您应该使用自己的标志名和逻辑,而不是我为示例代码编写的标志名和逻辑。如果您的逻辑更复杂,您可能更喜欢为每个标志使用单独的
If
语句,而不是像我那样将它们全部打包到一个单独的条件语句中。

所以您有一个文本文件,您希望读取其中的一些行,而不是其他行?你想读的行,你想从中返回信息吗?顺便说一句,在使用
eval()
函数进行类似操作时应该非常小心。首先,这不是maya特有的问题,因此如果您只是删除对它的任何引用,您可能会得到更多帮助。只需将
rawFile
作为
locatorsData
的一个参数,并删除
cmds
模块调用。此外,数据的布局似乎是造成复杂性的主要原因。您可以控制文件的写入方式吗?您可以使用支持序列化数据类型(如DICT和list)的or吗?我认为,如果您能提供您需要阅读的前几行文件的示例,将会有很大帮助。最后,只要文件不是非常大,将所有数据合并到一个结构中,然后提取您需要的内容可能更有意义。哇!非常感谢。这非常有帮助,我以自己的方式重新编写了代码,因为我对python非常陌生,而且一切都很完美!)