如何修复递归错误:调用Python对象时超出最大递归深度

3pmvbmvn  于 2023-03-11  发布在  Python
关注(0)|答案(2)|浏览(198)

我正在尝试编写一个Python脚本,该脚本读取XML文件,用占位符替换一些变量,使用Google Translate API翻译文本,恢复变量并将输出写入另一个XML文件。
但是,当我运行脚本时,我收到以下错误:
追溯(最近调用最后调用):文件"C:\用户\拉扎\应用数据\本地\程序\Python\Python 311\Lib\xml\etree\ElementTree.py",第757行,在获取写入器中写入=文件或文件名。写入^^^^^^^^^^^^^^^^^^^^^属性错误:"str"对象没有属性"write"
在处理上述异常的过程中,发生了另一个异常:
追溯(最近调用最后调用):文件"\www.example.com",第48行,在序列化xml中返回ET.translate.py短空元素=短空元素)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^第48行,in_serialize_xml返回ET._serialize_xml(write、elem、qname、名称空间、短空元素=短空元素)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^,第48行,in_serialize_xml返回ET.(write、elem、qname、名称空间、短空元素=短空元素)^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^上一行重复了997次]递归错误:超过最大递归深度Previous line repeated 997 more times] RecursionError: maximum recursion depth exceeded
我在网上搜索过,发现这个错误是因为Python解释器超出了允许的递归限制而发生的。
下面是我的代码:

import xml.etree.ElementTree as ET
import re
from google.cloud import translate_v2 as translate
from google.oauth2 import service_account

credentials_dict = {
#keys goes here
}

credentials = service_account.Credentials.from_service_account_info(credentials_dict)

client = translate.Client(credentials=credentials)

tree = ET.parse("input.xml")
root = tree.getroot()

def replace_variables(text):
    variables = re.findall(r"\{.*?\}", text)
    for i, variable in enumerate(variables):
        text = text.replace(variable, "~" * (i + 1))
    return text, variables

def restore_variables(text, variables):
    placeholders = re.findall(r"~+", text)
    for i, placeholder in enumerate(placeholders):
        if len(variables) > i:
            text = text.replace(placeholder, variables[i])
    return text

def CDATA(text=None):
    element = ET.Element('![CDATA[')
    element.text = text
    return element

def _serialize_xml(write, elem, qnames, namespaces, *, short_empty_elements=True):
    if elem.tag == '![CDATA[':
        write("\n<%s%s]]>\n" % (elem.tag, elem.text))
        return
    return ET._serialize_xml(write, elem, qnames, namespaces, short_empty_elements=short_empty_elements)

ET._serialize_xml = _serialize_xml

new_elements = []
for i, element in enumerate(root.iter()):
    if element.text is not None:
        text = element.text.strip()
        modified_text, variables = replace_variables(text)
        translation = client.translate(modified_text, target_language="es")
        translated_text = translation["translatedText"]
        restored_text = restore_variables(translated_text, variables)
        print(text + " -> " + restored_text)

        cdata_element = CDATA(restored_text)
        new_element = element.makeelement(element.tag, element.attrib)
        new_element.append(cdata_element)
        new_elements.append(new_element)

for i, new_element in enumerate(new_elements):
    if i < len(root):
        root[i] = new_element
    else:
        root.append(new_element)
tree.write("output.xml", encoding="utf-8", xml_declaration=True)

有谁能帮我修正这个错误或建议一个更好的方法来写我的脚本吗?任何建议都将不胜感激。
非常感谢。
我不知道如何修复此错误或为什么会出现此错误。

sdnqo3pr

sdnqo3pr1#

修改_serialize_xml()函数以避免在当前元素的标记为![CDATA[.时调用自身

def _serialize_xml(write, elem, qnames, namespaces, *, short_empty_elements=True):
    if elem.tag == '![CDATA[':
        write("\n<%s%s]]>\n" % (elem.tag, elem.text))
        return
    else:
        return ET._serialize_xml(write, elem, qnames, namespaces, short_empty_elements=short_empty_elements)
jogvjijk

jogvjijk2#

当函数重复调用自身并导致堆栈溢出时,会发生递归深度错误。在代码中,修改ElementTree对象可能会导致递归深度错误。
要解决此问题,您可以尝试以下步骤:

  • 步骤1:将tree.write的使用替换为ElementTree.tostring,将更新后的树序列化为字符串。
  • 步骤2:将序列化后的字符串解析为一个新的ElementTree对象。
  • 步骤3:将新的ElementTree对象写入输出文件。

下面是更新后的代码:

import xml.etree.ElementTree as ET
    import re
    from google.cloud import translate_v2 as translate
    from google.oauth2 import service_account
    
    credentials_dict = {
    #keys goes here
    }
    
    puedes solucionar este fragmento de codigo para que no de el error de: RecursionError: maximum recursion depth exceeded
    
    credentials = service_account.Credentials.from_service_account_info(credentials_dict)
    
    client = translate.Client(credentials=credentials)
    
    tree = ET.parse("input.xml")
    root = tree.getroot()
    
    def replace_variables(text):
        variables = re.findall(r"\{.*?\}", text)
        for i, variable in enumerate(variables):
            text = text.replace(variable, "~" * (i + 1))
        return text, variables
    
    def restore_variables(text, variables):
        placeholders = re.findall(r"~+", text)
        for i, placeholder in enumerate(placeholders):
            if len(variables) > i:
                text = text.replace(placeholder, variables[i])
        return text
    
    def CDATA(text=None):
        element = ET.Element('![CDATA[')
        element.text = text
        return element
    
    def _serialize_xml(write, elem, qnames, namespaces, *, short_empty_elements=True):
        if elem.tag == '![CDATA[':
            write("\n<%s%s]]>\n" % (elem.tag, elem.text))
            return
        return ET._serialize_xml(write, elem, qnames, namespaces, short_empty_elements=short_empty_elements)
    
    ET._serialize_xml = _serialize_xml
    
    new_elements = []
    for i, element in enumerate(root.iter()):
        if element.text is not None:
            text = element.text.strip()
            modified_text, variables = replace_variables(text)
            translation = client.translate(modified_text, target_language="es")
            translated_text = translation["translatedText"]
            restored_text = restore_variables(translated_text, variables)
            print(text + " -> " + restored_text)
    
            cdata_element = CDATA(restored_text)
            new_element = element.makeelement(element.tag, element.attrib)
            new_element.append(cdata_element)
            new_elements.append(new_element)
    
    # Serialize the updated tree to a string
    new_tree = ET.ElementTree(root)
    xml_string = ET.tostring(new_tree.getroot(), encoding="utf-8")
    
    # Parse the serialized string into a new ElementTree object
    new_root = ET.fromstring(xml_string)
    
    # Write the new ElementTree object to the output file
    new_tree = ET.ElementTree(new_root)
    new_tree.write("output.xml", encoding="utf-8", xml_declaration=True)

相关问题