In Python 2 I used:
print "a=%d,b=%d" % (f(x,n),g(x,n))
I've tried:
print("a=%d,b=%d") % (f(x,n),g(x,n))
In Python2, print was a keyword which introduced a statement:
print "Hi"
In Python3, print is a function which may be invoked:
print ("Hi")
In both versions, % is an operator which requires a string on the left-hand side and a value or a tuple of values or a mapping object (like dict) on the right-hand side.
So, your line ought to look like this:
print("a=%d,b=%d" % (f(x,n),g(x,n)))
Also, the recommendation for Python3 and newer is to use {}-style formatting instead of %-style formatting:
print('a={:d}, b={:d}'.format(f(x,n),g(x,n)))
Python 3.6 introduces yet another string-formatting paradigm: f-strings.
print(f'a={f(x,n):d}, b={g(x,n):d}')
The most recommended way to do is to use format method. Read more about it here
a, b = 1, 2
print("a={0},b={1}".format(a, b))
Simple printf() function from O'Reilly's Python Cookbook.
import sys
def printf(format, *args):
sys.stdout.write(format % args)
Example output:
i = 7
pi = 3.14159265359
printf("hi there, i=%d, pi=%.2f\n", i, pi)
# hi there, i=7, pi=3.14
Python 3.6 introduced f-strings for inline interpolation. What's even nicer is it extended the syntax to also allow format specifiers with interpolation. Something I've been working on while I googled this (and came across this old question!):
print(f'{account:40s} ({ratio:3.2f}) -> AUD {splitAmount}')
PEP 498 has the details. And... it sorted my pet peeve with format specifiers in other langs -- allows for specifiers that themselves can be expressions! Yay! See: Format Specifiers.
Simple Example:
print("foo %d, bar %d" % (1,2))
A simpler one.
def printf(format, *values):
print(format % values )
Then:
printf("Hello, this is my name %s and my age %d", "Martin", 20)
print("Name={}, balance={}".format(var-name, var-balance))
Because your % is outside the print(...) parentheses, you're trying to insert your variables into the result of your print call. print(...) returns None, so this won't work, and there's also the small matter of you already having printed your template by this time and time travel being prohibited by the laws of the universe we inhabit.
The whole thing you want to print, including the % and its operand, needs to be inside your print(...) call, so that the string can be built before it is printed.
print( "a=%d,b=%d" % (f(x,n), g(x,n)) )
I have added a few extra spaces to make it clearer (though they are not necessary and generally not considered good style).
You can literally use printf in Python through the ctypes module (or even your own C extension module).
On Linux, you should be able to do
import ctypes
libc = ctypes.cdll.LoadLibrary("libc.so.6")
printf = libc.printf
printf(b"Integer: %d\n"
b"String : %s\n"
b"Double : %f (%%f style)\n"
b"Double : %g (%%g style)\n",
42, b"some string", ctypes.c_double(3.20), ctypes.c_double(3.20))
On Windows, the equivalent would have
libc = ctypes.cdll.msvcrt
printf = libc.printf
As stated in the documentation:
None, integers, bytes objects and (unicode) strings are the only native Python objects that can directly be used as parameters in these function calls. None is passed as a C NULL pointer, bytes objects and strings are passed as pointer to the memory block that contains their data (char* or wchar_t*). Python integers are passed as the platforms default C int type, their value is masked to fit into the C type.
This explains why I wrapped the Python float objects using ctypes.c_double (FYI, a Python float is typically a double in C).
Output
Integer: 42
String : some string
Double : 3.200000 (%f style)
Double : 3.2 (%g style)
print("{:.4f} #\n".format(2))
Formatting helpful in situations like these.
You can refer to further details in the link below.
Python Formatting
Related
I've upgraded to pylint 2.15.2, and suddenly I'm getting lots of consider-using-f-string warnings whenever I run pylint, where I've used % formatting for strings. I understand why Pylint doesn't want to use the old % formatting, but I also get this error when I try to use string.format() instead. Take the following code as an example:
"""Example module"""
def some_long_complicated_function(a, b):
"""Do something"""
return a + b
def main():
"""Main function"""
a = 2
b = 3
percent_string = "The result of %s + %s is %s" % (
a, b, some_long_complicated_function(a, b)
)
format_string = "The result of {} + {} is {}".format(
a, b, some_long_complicated_function(a, b)
)
f_string = f"The result of {a} + {b} is {some_long_complicated_function(a, b)}"
print(percent_string)
print(format_string)
print(f_string)
if __name__ == "__main__":
main()
When I run pylint on this code, I get the following output:
************* Module pyexample
./pyexample.py:11:21: C0209: Formatting a regular string which could be a f-string (consider-using-f-string)
./pyexample.py:15:20: C0209: Formatting a regular string which could be a f-string (consider-using-f-string)
------------------------------------------------------------------
Your code has been rated at 8.46/10 (previous run: 6.15/10, +2.31)
There are instances like this where I don't want to use an f-string, because I think it actually hampers - not helps - readability, especially in cases like these where I may be writing long function calls inline within the string. In these places I'd rather use string.format(), because you can nicely separate out the format specifiers {} from the functions to generate the strings I want by putting them on a separate line. With f-strings, my lines may end up being too long and I have to resort to using line continuation characters, which again harms the readability IMO.
The problem is, Pylint doesn't like string.format() - it only wants me to use f-strings. I know that this is a 'Convention' not 'Error', but my code has to pass Pylint 100%. I could waive this message, but that's not good practice and there are places in my code where I do want to swap out the %-string formats.
My question:
Is there a way to configure Pylint so that when I run it, it will not flag a consider-using-f-string warning when I use string.format() (only when I use % strings)? I've had a look in the rc-file but I can't see any obvious setting like this.
Or is the only way to fix this to waive the warning entirely?
If you just want to avoid long line or line continuation character, I usually choose to use parentheses:
f_string = (f"The result of {a} + {b} is "
f"{some_long_complicated_function(a, b)}")
I got fed up last night and started porting PyVISA to Python 3 (progress here: https://github.com/thevorpalblade/pyvisa).
I've gotten it to the point where everything works, as long as I pass device addresses (well, any string really) as an ASCII string rather than the default unicode string (For example,
HP = vida.instrument(b"GPIB::16") works, whereas
HP = vida.instrument("GPIB::16") does not, raising a ValueError.
Ideally, the end user should not have to care about string encoding.
Any suggestions as to how I should approach this? Something in the ctypes type definitions perhaps?
As it stands, the relevant ctypes type definition is:
ViString = _ctypes.c_char_p
ctypes, like most things in Python 3, intentionally doesn't automatically convert between unicode and bytes. That's because in most use cases, that would just be asking for the same kind of mojibake or UnicodeEncodeError disasters that people switched to Python 3 to avoid.
However, when you know you're only dealing with pure ASCII, that's another story. You have to be explicit—but you can factor out that explicitness into a wrapper.
As explained in Specifying the required argument types (function prototypes), in addition to a standard ctypes type, you can pass any class that has a from_param classmethod—which normally returns an instance of some type (usually the same type) with an _as_parameter_ attribute, but can also just return a native ctypes-type value instead.
class Asciifier(object):
#classmethod
def from_param(cls, value):
if isinstance(value, bytes):
return value
else:
return value.encode('ascii')
This may not be the exact rule you want—for example, it'll fail on bytearray (just as c_char_p will) even though that could be converted quietly to bytes… but then you wouldn't want to implicitly convert an int to bytes. Anything, whatever rule you decide on should be easy to code.
Here's an example (on OS X; you'll obviously have to change how libc is loaded for linux, Windows, etc., but you presumably know how to do that):
>>> libc = CDLL('libSystem.dylib')
>>> libc.atoi.argtypes = [Asciifier]
>>> libc.atoi.restype = c_int
>>> libc.atoi(b'123')
123
>>> libc.atoi('123')
123
>>> libc.atoi('123') # Unicode fullwidth digits
ArgumentError: argument 1: <class 'UnicodeEncodeError'>: 'ascii' codec can't encode character '\uff10' in position 0: ordinal not in range(128)
>>> libc.atoi(123)
ArgumentError: argument 1: <class 'AttributeError'>: 'int' object has no attribute 'encode'
Obviously you can catch the exception and raise a different one if those aren't clear enough for your use case.
You can similarly write a Utf8ifier, or an Encodifier(encoding, errors=None) class factory, or whatever else you need for some particular library and stick it in the argtypes the same way.
If you also want to auto-decode return types, see Return types and errcheck.
One last thing: When you're sure the data are supposed to be UTF-8, but you want to deal with the case where they aren't in the same way Python 2.x would (by preserving them as-is), you can even do that in 3.x. Use the aforementioned Utf8ifier as your argtype, and a decoder errcheck, and use errors=surrogateescape. See here for a complete example.
I understand what print does, but of what "type" is that language element? I think it's a function, but why does this fail?
>>> print print
SyntaxError: invalid syntax
Isn't print a function? Shouldn't it print something like this?
>>> print print
<function print at ...>
In 2.7 and down, print is a statement. In python 3, print is a function. To use the print function in Python 2.6 or 2.7, you can do
>>> from __future__ import print_function
>>> print(print)
<built-in function print>
See this section from the Python Language Reference, as well as PEP 3105 for why it changed.
In Python 3, print() is a built-in function (object)
Before this, print was a statement. Demonstration...
Python 2.x:
% pydoc2.6 print
The ``print`` statement
***********************
print_stmt ::= "print" ([expression ("," expression)* [","]]
| ">>" expression [("," expression)+ [","]])
``print`` evaluates each expression in turn and writes the resulting
object to standard output (see below). If an object is not a string,
it is first converted to a string using the rules for string
conversions. The (resulting or original) string is then written. A
space is written before each object is (converted and) written, unless
the output system believes it is positioned at the beginning of a
line. This is the case (1) when no characters have yet been written
to standard output, (2) when the last character written to standard
output is a whitespace character except ``' '``, or (3) when the last
write operation on standard output was not a ``print`` statement. (In
some cases it may be functional to write an empty string to standard
output for this reason.)
-----8<-----
Python 3.x:
% pydoc3.1 print
Help on built-in function print in module builtins:
print(...)
print(value, ..., sep=' ', end='\n', file=sys.stdout)
Prints the values to a stream, or to sys.stdout by default.
Optional keyword arguments:
file: a file-like object (stream); defaults to the current sys.stdout.
sep: string inserted between values, default a space.
end: string appended after the last value, default a newline.
print is a mistake that has been rectified in Python 3. In Python 3 it is a function. In Python 1.x and 2.x it is not a function, it is a special form like if or while, but unlike those two it is not a control structure.
So, I guess the most accurate thing to call it is a statement.
In Python all statements (except assignment) are expressed with reserved words, not addressible objects. That is why you cannot simply print print and you get a SyntaxError for trying. It's a reserved word, not an object.
Confusingly, you can have a variable named print. You can't address it in the normal way, but you can setattr(locals(), 'print', somevalue) and then print locals()['print'].
Other reserved words that might be desirable as variable names but are nonetheless verboten:
class
import
return
raise
except
try
pass
lambda
In Python 2, print is a statement, which is a whole different kind of thing from a variable or function. Statements are not Python objects that can be passed to type(); they're just part of the language itself, even more so than built-in functions. For example, you could do sum = 5 (even though you shouldn't), but you can't do print = 5 or if = 7 because print and if are statements.
In Python 3, the print statement was replaced with the print() function. So if you do type(print), it'll return <class 'builtin_function_or_method'>.
BONUS:
In Python 2.6+, you can put from __future__ import print_function at the top of your script (as the first line of code), and the print statement will be replaced with the print() function.
>>> # Python 2
>>> from __future__ import print_function
>>> type(print)
<type 'builtin_function_or_method'>
Environment: python 2.x
If print is a built-in function, why does it not behave like other functions ? What is so special about print ?
-----------start session--------------
>>> ord 'a'
Exception : invalid syntax
>>> ord('a')
97
>>> print 'a'
a
>>> print('a')
a
>>> ord
<built-in function ord>
>>> print
-----------finish session--------------
The short answer is that in Python 2, print is not a function but a statement.
In all versions of Python, almost everything is an object. All objects have a type. We can discover an object's type by applying the type function to the object.
Using the interpreter we can see that the builtin functions sum and ord are exactly that in Python's type system:
>>> type(sum)
<type 'builtin_function_or_method'>
>>> type(ord)
<type 'builtin_function_or_method'>
But the following expression is not even valid Python:
>>> type(print)
SyntaxError: invalid syntax
This is because the name print itself is a keyword, like if or return. Keywords are not objects.
The more complete answer is that print can be either a statement or a function depending on the context.
In Python 3, print is no longer a statement but a function.
In Python 2, you can replace the print statement in a module with the equivalent of Python 3's print function by including this statement at the top of the module:
from __future__ import print_function
This special import is available only in Python 2.6 and above.
Refer to the documentation links in my answer for a more complete explanation.
print in Python versions below 3, is not a function. There's a separate print statement which is part of the language grammar. print is not an identifier. It's a keyword.
The deal is that print is built-in function only starting from python 3 branch. Looks like you are using python2.
Check out:
print "foo"; # Works in python2, not in python3
print("foo"); # Works in python3
print is more treated like a keyword than a function in python. The parser "knows" the special syntax of print (no parenthesis around the argument) and how to deal with it. I think the Python creator wanted to keep the syntax simple by doing so. As maverik already mentioned, in python3 print is being called like any other function and a syntx error is being thrown if you do it the old way.
Groovy has a concept of GStrings. I can write code like this:
def greeting = 'Hello World'
println """This is my first program ${greeting}"""
I can access the value of a variable from within the String.
How can I do this in Python?
--
Thanks
In Python, you have to explicitely pass a dictionary of possible variables, you cannot access arbitrary "outside" variables from within a string. But, you can use the locals() function that returns a dictionary with all variables of the local scope.
For the actual replacement, there are many ways to do it (how unpythonic!):
greeting = "Hello World"
# Use this in versions prior to 2.6:
print("My first programm; %(greeting)s" % locals())
# Since Python 2.6, the recommended example is:
print("My first program; {greeting}".format(**locals()))
# Works in 2.x and 3.x:
from string import Template
print(Template("My first programm; $greeting").substitute(locals()))
d = {'greeting': 'Hello World'}
print "This is my first program %(greeting)s" % d
You can't exactly...
I think the closest you can really get is using standard %-based substitution, e.g:
greeting = "Hello World"
print "This is my first program %s" % greeting
Having said that, there are some fancy new classes as of Python 2.6 which can do this in different ways: check out the string documentation for 2.6, specifically from section 8.1.2 onwards to find out more.
If your trying to do templating you might want to look into Cheetah. It lets you do exactly what your talking about, same syntax and all.
http://www.cheetahtemplate.org/
In Python 2.6+ you can do:
"My name is {0}".format('Fred')
Check out PEP 3101.