简体   繁体   中英

Why does .format(function()) not work, but % prints the value?

Code that I wrote:

def ball(f):  
    py_ball = f * 5
    u_ball = py_ball / 10  
    return py_ball, u_ball
print("py ball: {}, u ball: {}".format(ball(100)))

When I use str.format , it throws an exception:

Traceback (most recent call last):
  File "rear.py", line 5, in 
    print("py ball: {}, u ball: {}".format(ball(100)))
IndexError: tuple index out of range

But if I use % formatting:

print("py ball: %d, u ball: %d" % ball(100))

it works just fine and produces:

py ball: 500, u ball: 50

str.format() takes separate arguments for each slot, while % accepts a tuple or a single value. ball() returns a tuple, and that's a single argument as far as str.format() is concerned. Because your template has 2 slots, there is an argument missing for that second slot.

You have two options: Either accept a single argument for .format() and use formatting instructions to extract the nested elements, or pass in the tuple as separate arguments.

The latter can be done with the *expr call notation:

print("py ball: {}, u ball: {}".format(*ball(100)))

but the formatting specification lets you also address tuple elements:

print("py ball: {0[0]}, u ball: {0[1]}".format(ball(100)))

I used explicit numbering here to indicate that just one argument is expected, in position 0 ; 0[0] takes the first element of the tuple, 0[1] takes the second.

Your format string requires two arguments to .format , but you provide only one (which is a two-element tuple, but it is still one argument). On the other hand, % operator requires a single tuple as its right-hand argument, so it is OK. You could unpack your tuple using prefix asterisk operator:

b = ball(100)
print("py ball: {}, u ball: {}".format(*b))

The return value of ball() is a single value - a tuple.

When you call "...".format(ball(100)) you are passing that single value to a function that will eventually want two values.

When you call "..." % ball(100) you are supplying a tuple to the % operator, which expects a tuple!

Not surprisingly, it works in the second case and fails in the first case.

Try using the splat operator to flatten the tuple into the arguments of the call to .format , or try expanding the tuple yourself, or try using named parameter access in the .format call:

ball100 = ball(100)

"py ball: {}, u ball: {}".format(*ball100)   # splat! Flatten the tuple

"py ball: {}, u ball: {}".format(ball100[0], ball100[1]) # DIY

"py ball: {ball[0]}, u ball: {ball[1]}".format(ball=ball100) # named arg

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM