22

Original title:

"Help me understand this weird Python idiom? sys.stdout = codecs.getwriter('utf-8')(sys.stdout)"

I use this idiom all the time to print a bunch of content to standard out in utf-8 in Python 2.*:

sys.stdout = codecs.getwriter('utf-8')(sys.stdout)

But to be honest, I have no idea what the (sys.stdout) is doing. It sort of reminds me of a Javascript closure or something. But I don't know how to look up this idiom in the Python docs.

Can any of you fine folks explain what's going on here? Thanks!

Community
  • 1
  • 1

3 Answers3

33

.getwriter returns a functioncallable object; you are merely calling it in the same line.

Example:

def returnFunction():
    def myFunction():
        print('hello!')
    return myFunction

Demo:

>>> returnFunction()()
hello!

You could have alternatively done:

>>> result = returnFunction()
>>> result()
hello!

Visualization:

evaluation step 0: returnSomeFunction()()
evaluation step 1: |<-somefunction>-->|()
evaluation step 2: |<----result-------->|
ninjagecko
  • 77,349
  • 22
  • 129
  • 137
  • However, in this example the second set of parantheses is a *class instantiation operator*, not a function call. (See http://docs.python.org/tutorial/classes.html#class-objects) Also, please do not edit the question to match your answer. – Tugrul Ates Jun 27 '11 at 01:53
  • @junjanes: Thank you for pointing out that detail (though a "class instantiation operator" is in fact just class (callable object) or factory function (callable object)). You misinterpret though the rationale for editing: it is not to make my answer "match better", but rather to better summarize the question. (Incidentally, it does not in fact make my answer match better, anymore than it makes *your* answer match better.) In light of your concern though, I will re-add the original title in the question. – ninjagecko Jun 27 '11 at 23:42
6

codecs.getwriter('utf-8') returns a class with StreamWriter behaviour and whose objects can be initialized with a stream.

>>> codecs.getwriter('utf-8')
<class encodings.utf_8.StreamWriter at 0x1004b28f0>

Thus, you are doing something similar to:

sys.stdout = StreamWriter(sys.stdout)
Tugrul Ates
  • 8,756
  • 1
  • 30
  • 51
0

Calling the wrapper function with the double parentheses of python flexibility .

Example

1- funcWrapper

def funcwrapper(y):
    def abc(x):
        return x * y + 1
    return abc

result = funcwrapper(3)(5)
print(result)

2- funcWrapper

def xyz(z):
    return z + 1

def funcwrapper(y):
    def abc(x):
        return x * y + 1
    return abc

result = funcwrapper(3)(xyz(4))
print(result)
Sunil
  • 131
  • 1
  • 4