开发者

What do double parentheses mean in a function call? e.g. func(foo)(bar)

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.开发者_如何学Python 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!


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

This question is (very respectfully) like

What does x+y+z mean? I've seen x+y used, but what's this +z?.

Think of "order of operations".

Example:

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

Demo:

>>> returnFunction()()
hello!

You could have alternatively done:

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

Perhaps this makes this clearer?

>>> ( returnFunction() )()
hello!

Visualization:

evaluation step 0: returnSomeFunction()()
evaluation step 1: |<-somefunction>-->|()
evaluation step 2: |<----result-------->|

x '(' y ')' is, like most things, a non-terminal syntactical expression... as opposed to a terminal expression (i.e. an expression which cannot be embellished), or compiler directive (like #pragma or a print statement). In math-speak, it is just an expression.

So of course in say python2, print print 5 would by a syntactical error (since a print statement is basically a terminal expression). However, the function calls are non-terminal expressions (of which there can be many kinds, but this is probably a "python expression"), just like the pure mathematical functions they are inspired by. You can combine "python expressions" with operators and syntax which gives you a "python expression", and thus build more complicated expressions out of small ones. That is one of the essences of programming. (Replace "python" above with whatever programming language. Some languages call these EXPR when they define their syntax. This is a gross but accurate generalization. I'm not sure how my explanation changes as you consider things like operator fixity, associativity, non-grammar languages or preparsing extensions, etc.)


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)


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)
    
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜