Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

r"string" b"string" u"string" Python 2 / 3 comparison

I already know r"string" in Python 2.7 often used for regex patterns. I also have seen u"string" for, I think, Unicode strings. Now with Python 3 we see b"string".

I have searched for these in different sources / questions, such as What does a b prefix before a python string mean?, but it's difficult to see the big picture of all these strings with prefixes in Python, especially with Python 2 vs 3.

Question: would you have a rule of thumb to remember the different types of strings with prefixes in Python? (or maybe a table with a column for Python 2 and one for Python 3?)

NB: I have read a few questions+answers but I haven't found an easy to remember comparison with all prefixes / Python 2+3

like image 943
Basj Avatar asked Feb 05 '19 11:02

Basj


People also ask

What is the difference between text encoding in Python 2 and Python 3?

In Python 2, the str type was used for two different kinds of values – text and bytes, whereas in Python 3, these are separate and incompatible types. Text contains human-readable messages, represented as a sequence of Unicode codepoints. Usually, it does not contain unprintable control characters such as \0 .

What is U in Python string?

The 'u' in front of a string means the string is a Unicode string. A Unicode is a way for a string to represent more characters than a regular ASCII string can. In Python 2. x, a Unicode string is marked with 'u'.

What is R and b in Python?

b for bytes and r for raw.

What is R string in Python?

Python raw string is created by prefixing a string literal with 'r' or 'R'. Python raw string treats backslash (\) as a literal character. This is useful when we want to have a string that contains backslash and don't want it to be treated as an escape character.


2 Answers

From the python docs for literals: https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals

Bytes literals are always prefixed with 'b' or 'B'; they produce an instance of the bytes type instead of the str type. They may only contain ASCII characters; bytes with a numeric value of 128 or greater must be expressed with escapes.

Both string and bytes literals may optionally be prefixed with a letter 'r' or 'R'; such strings are called raw strings and treat backslashes as literal characters. As a result, in string literals, '\U' and '\u' escapes in raw strings are not treated specially. Given that Python 2.x’s raw unicode literals behave differently than Python 3.x’s the 'ur' syntax is not supported.

and

A string literal with 'f' or 'F' in its prefix is a formatted string literal; see Formatted string literals. The 'f' may be combined with 'r', but not with 'b' or 'u', therefore raw formatted strings are possible, but formatted bytes literals are not.

So:

  • r means raw
  • b means bytes
  • u means unicode
  • f means format

The r and b were already available in Python 2, as such in many other languages (they are very handy sometimes).

Since the strings literals were not unicode in Python 2, the u-strings were created to offer support for internationalization. As of Python 3, u-strings are the default strings, so "..." is semantically the same as u"...".

Finally, from those, the f-string is the only one that isn't supported in Python 2.

like image 198
Vitor SRG Avatar answered Sep 28 '22 15:09

Vitor SRG


  1. u-strings if for unicode in python 2. Most probably you should forget this, if you're working with modern applications — default strings in python 3 is all unicode, and if you're migrating from python 2, you'll most probably use from __future__ import unicode_literals, which makes [almost] the same for python 2

  2. b-strings is for raw bytes — have no idea of text, rather just stream of bytes. Rarely used as input for your source, most often as result of network or low-level code — reading data in binary format, unpacking archives, working with encryption libraries.

    Moving from/to b-string to str done via

    # python 3
    >>> 'hēllö'.encode('utf-8')
    b'h\xc4\x93ll\xc3\xb6'
    
    >>> b'h\xc4\x93ll\xc3\xb6'.decode()
    'hēllö'
    
    # python 2 without __future__
    >>> u'hēllö'.encode('utf-8')
    'h\xc4\x93ll\xc3\xb6'
    
    >>> 'h\xc4\x93ll\xc3\xb6'.decode('utf-8')
    u'h\u0113ll\xf6'  # this is correct representation
    
  3. r-strings is not specifically for regex, this is "raw" string. Unlike regular string literals, r-string doesn't give any special meaning for escape characters. I.e. normal string 'abc\n' is 4 characters long, last char is "newline" special character. To provide it in literal, we're using escaping with \. For raw strings, r'abc\n' is 5-length string, last two characters is literally \ and n. Two places to see raw strings often:

  • regex patterns — to not mess escaping with actual special characters in patters

  • file path notations for windows systems, as windows family uses \ as delimeter, normal string literals will look like 'C:\\dir\\file', or '\\\\share\\dir', while raw would be nicer: r'C:\dir\file' and r'\\share\dir' respectively

  1. One more notable is f-strings, which came to life with python 3.6 as simple and powerful way of formatting strings:
  • f'a equals {a} and b is {b}' will substitute variables a and b in runtime.
like image 43
Slam Avatar answered Sep 28 '22 13:09

Slam