简体   繁体   English

Python ruamel.yaml 代码在控制台中有效,但在 function (spyder) 中无效

[英]Python ruamel.yaml code works in console but not in function (spyder)

I am working in Spyder, Python version 3.9.我在 Spyder 工作,Python 3.9 版。 I am running into an issue where a bit of code I have written in a function isn't working, but when running the code in the console, I get the desired outcome.我遇到了一个问题,我在 function 中编写的一些代码无法正常工作,但是在控制台中运行代码时,我得到了预期的结果。

I am trying to write a function which takes items from a list and writes them to a YAML file.我正在尝试编写一个 function,它从列表中获取项目并将它们写入 YAML 文件。 When the code is in a function, I will get an error.当代码在 function 时,我会得到一个错误。 Below is a sample of what I would type in the console to try and run.下面是我将在控制台中键入以尝试运行的示例。 I copied over the function that I had written in the code block into the console and tried running the below.我将我在代码块中编写的 function 复制到控制台并尝试运行以下命令。

import ruaml.yaml
import pandas as pd

def getTable(tableDir):
    rawData = pd.read_csv(tableDir)
    tableData = pd.DataFrame(rawData)
    return tableData

def createYamlFile(tableDataLine, yamlFileName):
    yamlString = """

    """

    for i in range(0, len(tableDataLine), 1):
        yamlString = "{}{}\n".format(yamlString, tableDataLine[i]

    yaml = ruamel.yaml.YAML()
    yaml.preserve_quotes = True
    yamlContent = ruamel.yaml.safe_load(yamlString)

    with open(yamlFileName, 'w') as file:
        yaml.dump(yamlContent, file)

table = getTable(tableDir)
createYamlFile(table.iloc[0])

The desired outcome would look something like the following:期望的结果如下所示:

---
#0: Test0
1: Test1
2: Test2
#3: Test3
4: Test4

However, when I run the first code block in the console as-is, I get a ComposerError: expected a single document in the stream .但是,当我按原样在控制台中运行第一个代码块时,我得到一个ComposerError: expected a single document in the stream

When I run the exact same code in the console, outside of the function though eg当我在控制台中运行完全相同的代码时,在 function 之外,例如

table = getTable(tableDir)

yamlString = """

"""

for i in range(0, len(table.iloc[0]), 1):
    yamlString = "{}{}\n".format(yamlString, table.iloc[0][i])

yaml = ruamel.yaml.YAML()
yaml.preserve_quotes = True
yamlContent = ruamel.yaml.safe_load(yamlString)

with open(yamlFileName, 'w') as file:
    yaml.dump(yamlContent, file)

I am able to create my file just fine.我能够很好地创建我的文件。 The comments don't show up but this is a secondary problem to me.评论没有出现,但这对我来说是次要问题。 What is happening?怎么了? How come the exact same code in the console works when it's not in a function?为什么控制台中的完全相同的代码不在 function 中却能正常工作?

When you run this code:当您运行此代码时:

yaml_str = """\

"""

def fun():
    yaml_str = """

    """
    return yaml_str

print(repr(yaml_str))
print(repr(fun()))

it gives:它给:

'\n'
'\n\n    '

So your console and your program don't start with the same string.所以你的控制台和你的程序不会以相同的字符串开头。 Since your code "{}{}\n".format(yamlString, tableDataLine[i] essentially concatenates the table data a line at a time to that string, the first line gets indented, which is likely to cause an error.由于您的代码"{}{}\n".format(yamlString, tableDataLine[i]实质上是一次将表格数据一行连接到该字符串,因此第一行缩进,这很可能会导致错误。

If you want to specify YAML input code within a function (or any other indented environment) use either: yaml_str = "\n" or if you need readable multiline input use textwrap.dedent :如果您想在 function(或任何其他缩进环境)中指定 YAML 输入代码,请使用: yaml_str = "\n"或者如果您需要可读的多行输入,请使用textwrap.dedent

from textwrap import dedent

def fun():
    yaml_str = dedent("""\

    """)
    return yaml_str

print(repr(fun()))

which gives:这使:

'\n'

I always use a backslash escape after the starting triple quotes to get rid of the leading newline.我总是在开始的三重引号后使用反斜杠转义来摆脱领先的换行符。 You can also have multeline strings within a function that continue in the first column, but I find that unreadable.您还可以在 function 中包含多行字符串,这些字符串在第一列中继续,但我发现它不可读。


A far bigger problem is you mising the old API ( ruamel.yaml.safe_load() ) the new API (yaml = `ruamel.yaml.YAML()).一个更大的问题是你错过了旧的 API ( ruamel.yaml.safe_load() ) 新的 API (yaml = `ruamel.yaml.YAML())。 That will give problems and you should not be using the old API for any new code (if possible notify the place where you got this broken code example from).这会带来问题,您不应该将旧的 API 用于任何新代码(如果可能的话,请通知您从中获得此损坏代码示例的位置)。 Instead do use:而是使用:

import ruamel.yaml
from textwrap import dedent

def createYamlFile(tableDataLine, yamlFileName):
    yamlString = """

    """

    for i in range(0, len(tableDataLine), 1):
        yamlString = "{}{}\n".format(yamlString, tableDataLine[i])  # < closing parenthesis missing in non-console example

    yaml = ruamel.yaml.YAML()
    yaml.preserve_quotes = True
    yamlContent = yaml.load(yamlString)  # the default YAML() instance returns a subclass of the SafeLoader

    with open(yamlFileName, 'wb') as file:  # ruamel.yaml defaults to UTF-8, so use a binary file
        yaml.dump(yamlContent, file)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM