【问题标题】:Replacing strings with variables inside file in Python在Python中用文件内的变量替换字符串
【发布时间】:2020-02-03 11:02:38
【问题描述】:

我有一堆文件,在{my_var}{some_var} 等表单内有许多标签。我希望打开它们,并用我读过的my_varsome_var 替换它们蟒蛇。

为了做这些事情我一直在使用inspect.cleandoc()

import inspect, markdown
my_var='this'
some_var='that'
something=inspect.cleandoc(f'''
    All my vars are {some_var} and {my_var}. This is all.
''')
print(something)
#All my vars are that and this. This is all.

但我想通过读取文件 file1.mdfile2.md 来做到这一点

### file1.md
There are some strings such as {my_var} and {some_var}.
Done.

### file2.md
Here there are also some vars: {some_var}, {my_var}. Also done.

这是 Python 代码:

import inspect, markdown
my_var='this'
some_var='that'

def filein(file):
    with open(file, 'r') as file:
        data = file.read()
    return data

for filei in ['file1.md','file2.md']:
    fin=filein(file)
    pre=inspect.cleandoc(f'''{fin}''')

但是,上面没有评估 filei 中的字符串并将它们替换为 this (my_var) 和 that (some_var),而是将它们保留为字符串 {my_var} 和 @987654339 @。

我做错了什么?

【问题讨论】:

  • inspect.cleandoc 应该做什么?
  • 这能回答你的问题吗? Replace string within file contents
  • @bereal appologies,有人接受了排除我序言的编辑。我已经编辑了我的输入。
  • @ZarakiKenpachi 不是真的,因为我想避免为每个变量替换定义一个替换:在这个工作案例中,我建议使用 2 个变量,所以很容易。但在我的真实案例中,我将许多变量导入 python,这意味着我明确指定了每个变量替换。
  • @usr2564301 抱歉,我正在尝试修复该函数,因为它会由于缩进而产生“未定义的数据变量”错误。下次我会尽量小心一点。

标签: python


【解决方案1】:

您可以使用.format 方法。

您可以使用** 向其传递包含该变量的字典。

因此,您可以使用 locals()globals(),它们是所有局部变量和全局变量的字典。

例如

text = text.format(**globals())

完整代码:

my_var="this"
some_var="that"

for file in ["file1.md", "file2.md"]:
    with open(file, "r") as f:
        text = f.read()
    text = text.format(**globals())
    print(text)

【讨论】:

  • 太棒了!没想过通过**globals(),但这解决了我的问题。
  • 一般.format(**locals()) 可以“模拟” f-strings。我主要在我的脚本中使用它,因为它同时兼容 python 2 和 3,所以我不必担心 python 版本。
【解决方案2】:
  • f-strings 是一种静态替换机制,它们是字节码的固有部分,而不是通用模板机制
  • 我不知道你认为inspect.cleandoc 做了什么,但它不会那样做。
  • Python 通常会避免使用魔法,这意味着除非您专门制作它,否则它实际上不会对您的局部变量大惊小怪,这里不是这种情况。 Python 通常使用明确提供的 dicts(某些术语与其替换的映射)。

我猜你想要的是 format/format_map 方法,它适用于使用 {} 的格式字符串,例如

filein(file).format(my_var=my_var, some_var=some_var)

如果您正在阅读的文件处于第三方的控制之下,这可能会有风险:str.format 允许属性访问,因此最终提供了用于执行任意代码的工具。在这种情况下,像 string.Template 这样的工具、旧式字符串替换 (%) 或适当的模板引擎可能是一个更好的主意。

【讨论】:

  • 亲爱的 Masklinn,感谢您的 cmets。我编辑了我的问题以解释我是如何使用inspect.cleandoc(),因为它已从我之前的编辑中删除。我也在从另一个文件中读取变量,我想知道是否有一种方法可以直接使用它们,而不必在.format() 下指定所有变量?我很感激你的cmets
  • cleandoc 调用仍然没有意义(它是 f-string 的工作)。您可以使用 format_map 并给它一个映射(映射),或者使用 str.format 的“参数解包”以获得相同的效果(str.format(**params)),两者都要求您可以以某种方式将您的替换作为 Python dict。跨度>
猜你喜欢
  • 1970-01-01
  • 2021-05-15
  • 2019-03-28
  • 1970-01-01
  • 2020-07-09
  • 2014-10-29
  • 2019-08-27
  • 1970-01-01
  • 2011-09-29
相关资源
最近更新 更多