Python string formatting

When handling small SQL formatting, I was amazed to find that I could bind string formatting:

def get_sql(table, limit=True): sql = "select report_date from %s" if limit: result = "%s limit 1" % sql % table else: result = sql % table return result 

It is legal? Any reason not to do this?

+4
source share
4 answers

It makes sense that this works because this statement looks like this:

'some value goes here %s' % value

Actually returns a string. This is probably more logical for viewing it as follows:

result = ("%s limit 1" % sql) % table

There is nothing obviously wrong with this, but chain operators can lead to problems figuring out where the error came from.

So, for example, this works great:

 >>> sql = 'a value of %s' >>> x = 'some string %s with stuff' >>> y = 'VALUE' >>> x % sql % y 'some string a value of VALUE with stuff' 

But if there was a formatting error (I understand that this example is pathological, but it gets the point):

 >>> sql = 'a value of %d' >>> x = 'some string %d with stuff' >>> y = 123 >>> x % sql % y Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: %d format: a number is required, not str 

It is actually unclear which %d is causing your error. For this reason, I would split it and just use one % formatter per line, if possible, because then the trace will be able to tell you exactly which line and in which formatting the problem occurred.

For writing, by doing this with one formatting per line, you will also make life easier for others who need to read your code and try to figure out what is going on.

+4
source

This is completely legal.

the " single argument " form of formatting strings is a really special case - a tuple is usually used for several elements, and this leads to a more obvious example of why this is normal

 result = "%s limit 1" % (sql % (table,),) 

This ^ was originally written to prompt the questioner that support for several formats is a legitimate language function, but, as Nas Banov notes, she reads as if I'm trying to explain how it works (screwing up the code did not help). It does not build the line from right to left, as it suggests that it is possible, but HAS to create it (be associative) from left to right. The operator must take the line on the left and return one, but can take a non-line (tuple) on the right. Since you cannot use% on a pair of tuples, it cannot work in reverse

 >>> "%s %f %s" % ( "%d", 0.1, "%d %d" ) % (1,2,3) '1 0.100000 2 3' 

This can, however, lead to complex / dirty code, so personally I would use it very sparingly.

You can use your example as follows:

 def get_sql(table, limit=True): sql = "select report_date from" strlimit = "" if limit: strlimit = "limit 1" return "%s %s"%(sql, strlimit) 
+3
source

Why yes, you can associate% string formatting with this, even if this is the first time I see that it is being used (and horribly, mind you)!

The reason is that operators of the same type are group left to right (have “left associativity” - with noticeable exceptions of raising to the power ** and comparing a<b<c ).

So, just like

 >>> 1 - 2 - 3 # equals to (1-2)-3 -4 >>> 16 / 4 / 2 # equals to (16 /4) /2, NOT 16 / (4 / 2) 2 

therefore s1 % s2 % s3 is equal to (s1 % s2) % s3

Oh, and by the way, it doesn’t matter if s1, s2 and s3 are strings or numbers - the compiler does not know that at compile time and only at run time it will be determined that % means "remainder of division", (if s1 - number) or string formatting (if s1 is a string).

+2
source

I would write it like this:

 def get_sql(table,limit=True): sql = "select report_date from %s"%table if limit: sql += " limit 1" return sql 

PS. The code you posted works as follows:

 In [49]: "%s limit 1" % sql Out[49]: 'select report_date from %s limit 1' In [50]: "%s limit 1" % sql % 'table' Out[50]: 'select report_date from table limit 1' 

Of course, you can do this, but I do not think this is particularly clear.

0
source

Source: https://habr.com/ru/post/1315983/


All Articles