Python 如何在字符串格式化期间使用分配给变量的值?

Python 如何在字符串格式化期间使用分配给变量的值?,python,string,string-formatting,Python,String,String Formatting,所以这是可行的: >>> 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 = 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
是函数调用,我不想在字符串格式化过程中重新计算它们)

您可以使用
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'

您可以使用
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'
最具pythonic(在本例中是可读的)解决方案不是使用lambda函数,而是在
format()
调用之前缓存
a
b

a = function_x()
b = function_y()
"a={a}, b={b}, a+b={c}".format(a=a, b=b, c=a+b)
从现在起6个月后查看代码时,您会心存感激。

最具python风格(在本例中是可读的)解决方案不是使用lambda函数,而是在
format()
调用之前缓存
a
b

a = function_x()
b = function_y()
"a={a}, b={b}, a+b={c}".format(a=a, b=b, c=a+b)
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) )
从现在起6个月后,当您查看代码时,您会心存感激

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}”。格式(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=x
b
中的对象相同 因为
=
左侧的任何标识符都在
format()
的本地命名空间中,而
=
右侧的任何标识符都在函数
format()
之外的命名空间中
顺便说一下,这就是为什么左边的标识符称为参数,右边的标识符是作为参数传递的对象的标识符

其次,如果要避免写入两次
f()
(一次作为单独的参数,一次在表达式
f()+g()
中),以及
g()
中,这意味着您只想写入一次作为单独的参数。
所以,如果我很了解你,你基本上希望写这样的东西:
“a={a},b={b},a+b={}”。格式(a=f(),b=g())

对于当前的方法
str.format
,这个带有三个替换字段{}的表达式显然是不正确的

不管怎样,让我们重新定义方法
格式
!然后可以只将两个参数传递给
format()

结果

p : a={}, b={}, a+b={}
a=101, b=45, a+b=146
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
我们甚至可以做更复杂的事情:

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())
从系统导入退出
进口稀土
def fx():返回333
def fy():返回6
帕特班(str):
定义初始值(self,s):
对于findall(')(?

编辑 我认为你的问题写错了,这导致了对它的模糊理解,然后是错误的答案

x
y
不是函数调用。它们看起来只是标识符

如果您调用函数调用,我认为这是因为,事实上,您希望获得这样的结果:
“a={a},b={b},a+b={c}”。格式(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=x
b
中的对象相同 因为
=
左侧的任何标识符都在
format()
的本地命名空间中,而
=
右侧的任何标识符都在函数
format()
之外的命名空间中
顺便说一下,这就是为什么左边的标识符称为参数,右边的标识符是作为参数传递的对象的标识符

其次,如果要避免写入两次
f()
(一次作为单独的参数,一次在表达式
f()+g()
中),以及
g()
中,这意味着您只想写入一次作为单独的参数。
所以,如果我很了解你,你基本上希望写这样的东西:
“a={a},b={b},a+b={}”。格式(a=f(),b=g())

对于当前的方法
str.format
,这个带有三个替换字段{}的表达式显然是不正确的

不管怎样,让我们重新定义方法
format
!然后只可以将两个参数传递给
format()

结果

p : a={}, b={}, a+b={}
a=101, b=45, a+b=146
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
我们甚至可以做更复杂的事情:

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())
从系统导入退出
进口稀土
def fx():返回333
def fy():返回6
帕特班(str):
定义初始值(self,s):
对于findall(')(?