You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Android式字符串资源实现多语言XML本地化及动态切换问题

模仿Android多语言字符串资源实现方案

我想要模仿Android的字符串资源使用方式,把项目里的硬编码字符串替换成多语言XML引用,但没找到现成的实现方案。

多语言XML文件示例

en_gb.xml

<resource>
  <section1>
    <string name="hello">Hello</string>
    <string name="bye">Goodbye</string>
  </section1>
  <section2>
    <string name="world">World</string>
    <string name="end">!</string>
  </section2>
</resource>

jp_tr.xml

<resource>
  <section1>
    <string name="hello">こんにちは</string>
    <string name="bye">さようなら</string>
  </section1>
  <section2>
    <string name="world">世界</string>
    <string name="end">!</string>
  </section2>
</resource>

已弃用的exec实现方式

最初我通过ElementTree和exec()可以基于上述XML文件构建类:

class en_gb:
    tr = ET.parse(r'.\assets\local\en_gb.xml')
    for rs in tr.getroot():
        exec(f'class {rs.tag}:pass')
        for c in rs:
            exec(f'{rs.tag}.{c.attrib["name"]}=str("{c.text}")')

生成的结构支持lang.section.strname形式调用:

from localization import en_gb, jp_tr
lang = en_gb
print(lang.section1.hello) #> Hello
lang = jp_tr
print(lang.section2.world) #> 世界

后来我想自动生成所有基础类,但找不到在类中动态添加类的正确方法。尝试了以下代码:

import xml.etree.ElementTree as ET
import os
from pathlib import Path
for lang in os.listdir('.\assets\local\\'):
    lang = Path(language).stem
    exec(f'class {lang}:pass')
    for rs in ET.parse(fr'.\assets\local\{lang}.xml').getroot():
        exec(f'class{lang}.{rs.tag} = class {rs.tag}:pass')
        for c in rs:
            exec(f'{rs.tag}.{c.attrib["name"]}=str("{c.text}")')

但en_gb.base = class base:pass不是有效语法,卡在这里了。我期望生成的原生类结构如下:

class en_gb:
    class section1:
        hello = "Hello"
        bye = "Goodbye"
    class section2:
        world = "World"
        end = "!"
class jp_tr:
    class section1:
        hello = "こんにちは"
        bye = "さようなら"
    class section2:
        world = "世界"
        end = "!"

改用SimpleNamespace后的问题

我换成SimpleNamespace实现,但无法通过local类切换语言:

class local(object):
    def __init__(self, lang="en_gb"):
        l = localization()
        self = getattr(l.langs, lang)
    def set_lang(self, lang:str):
        self = getattr(l.langs, lang)

class localization:
    def __init__(self, lang="en_gb"):
        langs = {}
        for language in list(Path('./assets/local/').glob('*.xml')):
            l_name = Path(language).stem
            tree = ElementTree.parse(f".\assets\local\{l_name}.xml")
            d = {}
            for child in tree.getroot():
                tmp = {}
                for c in child:
                    tmp[c.attrib['name']] = c.text
                d[child.tag] = SimpleNamespace(**tmp)
            langs[l_name] = SimpleNamespace(**d)
        self.langs = SimpleNamespace(**langs)
    def __get__(self):
        print("getting")
        return self.langs

测试代码中,直接调用localization类有效,但local类无法访问属性也不能切换语言:

l = localization()
print(l.langs.en_gb.section1.hello) ## 此代码有效

lg = local()
print(lg.section1.hello) ## 此代码无效
# 应支持动态切换语言
lg.set_lang('jp_tr')
print(lg.section1.hello) ## 应输出こんにちは

内容的提问来源于stack exchange,提问作者Scott Paterson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 20:40:47