提问:format格式化函数

小白提问,一个累乘函数

def cmul(a, *b):
    m = a
    for i in b:
        m *= i
    return m

如果用

print(eval(cmul(input())))

输入1,2,3,4,等于只传入了一个tuple,所以输出(1,2,3,4)。
可是用format函数就能打印期望的结果,为什么呢?

print(eval("cmul({})".format(input())))

输出24

代码加入3行输出语句,如下:

def cmul(a, *b):
    print(a)
    print(b)
    m = a
    for i in b:
        m *= i
        print(i)
    return m

代码运行结果如下:

print(eval(cmul(input())))

键盘输入:
1,2,3,4
运行结果:
UnboundLocalError: local variable 'i' referenced before assignment #局部变量 i 未赋值
1,2,3,4 #a
() #b

解释:
把元组看作一个变量传递给变量a,b是空的,循环变量 i 没有得到赋值(因为 b是空的),for循环无用;

print(eval("cmul({})".format(input())))

键盘输入:

1,2,3,4
运行结果:

1 #a
(2, 3, 4) #b
4 #i的最终值
24 #print(eval("cmul({})".format(input())))运行结果

解释:
使用了format,即将(1,2,3,4)中的1赋值给a,剩下的赋值给b,for循环正常运行,得到正确结果。

你的format() 相当于 是在给字符串 "cmul({})"加入 1,2,3,4 得到的结果是: 一个str cmul(1,2,3,4), 其实这个时候是没有执行函数, 而是在 eval 的时候执行了函数,这时执行的时候它就相当于是四个单独的值, 所以a得到了1 而*b得到了234, 所以你得到了你想要的结果

而你的第一个 cmul 其实传给函数的是一个参数 str "1,2,3,4" 所以 a 得到了它 , *b 只得到了一个空元祖..所以你的for循环根本没用上 直接返回了m 而你的m= a 所以是str "1,2,3,4"再使用evel最终给你返回的是元祖

input()是一个字符串,通过格式化.format()方法处理,就变成了一个新的字符串”cmul({})":
假如输入1,2,3,4,也就是
Input() = "1,2,3,4",
格式化处理:
“cmul({})".format(input()) = "cmul(1,2,3,4)"
以上是一个字符串,那就要用eval
eval(“cmul({})".format(input()) = eval("cmul(1,2,3,4)") =cmul(1,2,3,4)
然后就执行函数。