基于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
相关产品推荐
相关产品推荐

