Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the b'' sentinel mean in Python iter()?

Tags:

python

Let's say I have a process that returns a bunch of lines, which I want to iterate through:

import subprocess

myCmd = ['foo', '--bar', '--baz']
myProcess = subprocess.Popen(myCmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for myLine in iter(myProcess.stdout.readline, b''):
    print myLine

What does the sentinel argument to iter() do in this example, where I pass it the value b''? I think I understand '' by itself — I stop iterating on an empty line — but I don't know what b'' means.

like image 879
Alex Reynolds Avatar asked Mar 19 '13 07:03

Alex Reynolds


People also ask

What is Sentinel in ITER Python?

We can pass one more argument to Python iter() . This second argument is called the sentinel element. If we pass this sentinel element, the iterator will keep generating values until the generated value equals this sentinel value, after which StopIteration will be raised.

What is ITER () in Python?

python iter() method returns the iterator object, it is used to convert an iterable to the iterator. Syntax : iter(obj, sentinel) Parameters : obj : Object which has to be converted to iterable ( usually an iterator ). sentinel : value used to represent end of sequence.


2 Answers

In python3 the string is a byteliteral. Ignored in python 2.

like image 68
Gjordis Avatar answered Oct 27 '22 05:10

Gjordis


I'll try my best to be more precise than what I read so far. (Slightly revised version)

The Python notation b'string' denotes a byte string literal in Python versions which supports it. The notation has been introduced with PEP 358 for Python 2 as a step towards the migration to unicode support. The current Python syntax for 2.6 does not mention the b prefix while the Python syntax for 2.7 does mention the b prefix. However, PEP 358 was intended for Python 2.6 and all Python 2.6 interpreters which I have seen accept it.

With the migration to Python 3, the default for string literals changed from byte to unicode. However, the __future__ module was introduced to ease migration. The following illustrates the effect with respect to string literals.

Python 2.6.6 (r266:84292, Dec 26 2010, 22:31:48) 
[GCC 4.4.5] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 'abc'
'abc'
>>> b'abc'
'abc'
>>> from __future__ import unicode_literals
>>> 'abc'
u'abc'
>>> b'abc'
'abc'

I hope I could motivate that the following statements have a limited validity:

  • In Python 3 this denotes a byte literal: Yes, but also in Python 2 at least since version 2.6.
  • This notation is ignored in Python 2: It is more that it has no effect if you have a Python 2 version which already supports it and unless you (or the foreign code you look at) imports __future__ and only if you do not care about compatibility with Python 3 (which everyone should consider and which is often aimed at in third party software).

The shortest valid answer to the OP's question, in my view, would be:

This is a prefix for string literals, enforcing byte representation as opposed to unicode representation, introduced in Python 2.6, not changing the Python default for Python 2 (but deserves attention if from __future__ import can be seen).

like image 4
class stacker Avatar answered Oct 27 '22 07:10

class stacker