Python 以旧代码计算的格式字符串执行计算
我正在使用一个函数Python 以旧代码计算的格式字符串执行计算,python,string,string-formatting,Python,String,String Formatting,我正在使用一个函数foo(来自一个我无法修改的外部包),该函数接受、填充并输出一个字符串。我想通过对该字符串中允许的间隙填充符进行简单的算术来操作输出 更明确地说: 我现在调用foo('Finished{n}of{n}'),我得到,比如说,完成了5个作业中的3个 我想做foo({N-N}left)来获得2个剩余工作 目前这不起作用。我怀疑foo只是对传递给它的字符串调用format,显然N-N甚至不是有效的Python变量名 问题:有没有办法欺骗格式化来进行我想要的计算?丑陋的黑客是受欢迎的 编
foo
(来自一个我无法修改的外部包),该函数接受、填充并输出一个字符串。我想通过对该字符串中允许的间隙填充符进行简单的算术来操作输出
更明确地说:
我现在调用foo('Finished{n}of{n}')
,我得到,比如说,完成了5个作业中的3个
我想做foo({N-N}left)
来获得2个剩余工作
目前这不起作用。我怀疑foo
只是对传递给它的字符串调用format
,显然N-N
甚至不是有效的Python变量名
问题:有没有办法欺骗格式化来进行我想要的计算?丑陋的黑客是受欢迎的
编辑:这是针对Python3的
EDIT2:我无法访问变量N
和N
。它们是foo的内部
EDIT3:假设foo
实际上只对传递给它的字符串执行。format
操作,则给出可能的和不可能的最小示例:
import sys
def foo(s):#This function cannot be changed
N=5
n=3
sys.stderr.write(s.format(N=N,n=n))
foo('Finished {n} out of {N}')
foo('{N-n} left') # Error
在Python3.6+中,可以使用格式化的字符串文本(),也称为f字符串
n = 3
N = 5
x = f'Finished {n} out of {N}'
y = f'{N-n} jobs left'
结果:
print(x, y, sep='\n')
Finished 3 out of 5
2 jobs left
如果愿意,您可以简单地将其包装到函数中。试试:
foo('{} left'.format(N-n))
这应该可以完成任务。这是Python字符串格式化功能的一个非常简单的示例
根据你修改过的问题定义,这里有一个建议的方法来做你想做的事情,但它绝对不是琐碎的。它基于修改函数foo
的Python抽象语法树
需要执行以下步骤:
- 仅当
foo
函数只有字节码时,才需要此步骤
- 找到第三方反编译器,它将生成Python源代码
- 为
foo
函数生成源代码
- 使用
ast.Parse()
解析源代码
- 在函数中找到
N
和N
可靠可用的位置
- 如果已经有可以重写的print语句,请将其替换为代码,否则将print语句插入树中
- 使用
AST.Compile()
编译AST
- 使用结果函数对象代替原始函数
您将需要一个非常强大的用例,因为这将是大量的学习和工作。如果没有实际的foo
函数,我可以提供的功能就很少了。我相信,通过调整Python的属性查找(如lazify
包所做的),然后在堆栈中搜索调用者的局部变量,这是可能的,但是我放弃了这种方法,因为事情很快就会变得一团糟。假设foo
是我们目前认为的那样,为什么不为这个特定的情况对Python的string
功能进行子类化呢
class FooString(str):
def format(self, **kwargs):
if "n" not in kwargs or "N" not in kwargs:
raise ValueError("Perhaps we're mistaken about foo?")
return "Finished {n} out of {N}\n{left} left".format(
left=kwargs["N"] - kwargs["n"], **kwargs)
然后,调用foo(FooString())
应该会产生所需的输出
>>>print(FooString().format(n=1, N=10))
<<<Finished 1 out of 10
9 left
打印(FooString().format(n=1,n=10))
这是用于Python 2还是3的?@Jonathan Python 3I无法访问变量N
和N
。它们是foo
的内部函数,foo是您可以修改的函数吗?否;对于这个问题,它应该被认为是封闭的源代码,感谢您勾勒出复杂的方法。我认为我的用例不够重要,我会让输出的读者自己计算;)我无法访问变量N
和N
。它们是foo
的内部,然后在foo
函数中构造字符串?foo
来自外部包我认为您应该提供一个。模拟一个示例“不可触及”函数foo
,向我们展示如何使用它,以及您想要什么。否则,你的问题很难理解。添加了最小、完整和可验证的示例