这样可行:
>>> x = 1
>>> y = 2
>>> "a={a}, b={b}, a+b={c}".format( a=x, b=y, c=x+y )
'a=1, b=2, a+b=3'
但这并不是:
>>> "a={a}, b={b}, a+b={c}".format( a=x, b=y, c=a+b )
NameError: name 'a' is not defined
有没有办法让第二个工作? (比如说x
和y
是函数调用,我不想在字符串格式化过程中重新计算它们。
答案 0 :(得分:3)
对于此,最pythonic(在这种情况下是可读的)解决方案不是使用lambda函数,而是在a
调用之前缓存b
和format()
:
a = function_x()
b = function_y()
"a={a}, b={b}, a+b={c}".format(a=a, b=b, c=a+b)
从现在起6个月后查看代码,你会感激不尽。
答案 1 :(得分:1)
您可以使用lambda
:
def x():
return 1
def y():
return 2
>>> "a={a},b={b}, a+b={c}".format(**(lambda a=x(),b=y():{'a':a,'b':b,'c':a+b})())
'a=1,b=2, a+b=3'
这个lambda表达式等于调用预定义函数:
def twosumm(a, b):
return {'a':a, 'b':b, 'c': a+b}
>>> "a={a},b={b}, a+b={c}".format(**twosumm(x(), y()))
'a=1,b=2, a+b=3'
我还认为最好使用简单易读的解决方案,只需致电x()
和y()
即可在形成之前获得结果:
>>> a, b = x(), y()
>>> "a={a},b={b}, a+b={c}".format(a=a, b=b, c=a+b)
'a=1,b=2, a+b=3'
答案 2 :(得分:0)
x = 1
y = 2
def f(x,y):
return (x,y,x+y)
print "a={}, b={}, a+b={}".format( *f(x,y) )
# or
print "a={0[0]}, b={0[1]}, a+b={0[2]}".format( f(x,y) )
我认为你的问题写错了,导致对它的理解模糊,然后是错误的答案。
x
和y
不是函数调用。如它们所示,它们只是标识符
如果你唤起函数调用,我认为这是因为,事实上,你希望获得类似的结果:
"a={a}, b={b}, a+b={c}".format( a=f(), b=g(), c=f()+g() )
但无需编写c=f()+g()
,因为它意味着f()
和g()
分别执行了两次。
首先,在Python中永远不可能写出.format( a=x, b=y, c=a+b )
或.format( a=f(), b=g(), c=a+b )
之类的内容,其中a
和b
中的c=a+b
将引用相同的内容a
和b
中的a=x
和b=y
对象
因为=
左侧的任何标识符都位于format()
的本地名称空间中,而=
右侧的任何标识符都位于函数format()
之外的名称空间中。
顺便说一下,这就是为什么左边的标识符被称为参数,右边的标识符是作为参数传递的对象的标识符。
其次,如果你想避免两次写f()
(一次作为单独的参数,一次在表达式f()+g()
中),而g()
则相同,这意味着你只想写一次,就像单独的论点一样
所以,如果我理解你,你基本上希望写出类似的东西:
"a={a}, b={b}, a+b={}".format( a=f(), b=g() )
使用当前方法str.format
,具有三个替换字段{}的此表达式显然不正确。
无论如何,让我们重新定义方法format
!然后,只能将两个参数传递给format()
。
def fx(): return 101
def fy(): return 45
class Pat(str):
def __init__(self,s):
self = s
def format(self,x,y):
return str.format(self,x,y,x+y)
p = Pat("a={}, b={}, a+b={}")
print 'p==',p
print p.format(fx(),fy())
结果
p : a={}, b={}, a+b={}
a=101, b=45, a+b=146
我们甚至可以做更复杂的事情:
from sys import exit
import re
def fx(): return 333
def fy(): return 6
class Pat(str):
def __init__(self,s):
for x in re.findall('(?<=\{)[^}]+(?=\})',s):
if x not in ('A','M'):
mess = " The replacement field {%s] isn't recognised" % x
exit(mess)
self.orig = s
self.mod = re.sub('\{[^}]*\}','{}',s)
def modif(self,R):
it = iter(R)
return tuple(sum(R) if x=='{A}'
else reduce(lambda a,b: a*b, R) if x=='{M}'
else next(it)
for x in re.findall('(\{[^}]*\})',self))
def format(self,*args):
return ''.join(self.mod.format(*self.modif(args)))
print Pat("a={}, b={}, a+b={A}").format(fx(),fy())
print '******************************************'
print Pat("a={}, b={}, c={}, a+b+c={A}").format(fx(),fy(),5000)
print '******************************************'
print Pat("a={}, b={}, a*b={M}").format(fx(),fy())
print '******************************************'
print Pat("a={}, b={}, axb={X}").format(fx(),fy())
结果
a=333, b=6, a+b=339
******************************************
a=333, b=6, c=5000, a+b+c=5339
******************************************
a=333, b=6, a*b=1998
******************************************
Traceback (most recent call last):
File "I:\potoh\ProvPy\Copie de nb.py", line 70, in <module>
print Pat("a={}, b={}, axb={X}").format(fx(),fy())
File "I:\potoh\ProvPy\Copie de nb.py", line 51, in __init__
exit(mess)
SystemExit: The replacement field {X] isn't recognised