简体   繁体   中英

Can someone explain the Python “function” concept in this context to me?

How are you supposed to access the 10 in this? I've been informed we're returning a function in this function, but how does this make sense?

function([1, 2, 3, 4])(10)

I'm assuming a lot based on the limited information you've provided in your question.
But it looks like you trying to understand a functional closure. Here's a totally contrived example:

def function(a):
    def inner(b):
        return sum(a) == b
    return inner

>>> function([1,2,3,4])(10)
True
>>> eq = function([1,2,3,4])
>>> eq(10)
True
>>> eq(11)
False

In your expression function([1, 2, 3, 4])(10) , there are two calls , one with the argument [1, 2, 3, 4] and the other with the argument 10 . For this to work, function must be a callable that returns a callable. Python relies heavily on objects having types which define their behaviour, and callability is one of those behaviours, recursively defined by objects having a __call__ method (which is a type of callable). Because of this dynamic behaviour, we can't tell from the expression what type function is.

We can provide examples that would make the expression valid, though. For instance:

function = lambda x: x.__contains__

This creates an anonymous function using a lambda expression, which is a callable. That function returns a bound method (assuming its argument has the __contains__ method) which in turn is callable, and the expression would evaluate to False .

class function:
    def __init__(self,a):
        "Method called during object initialization"
        # Note that the return value doesn't come from this method.
        # self is created before it is called and returned after.
    def __call__(self,b):
        "Method called when the object is called"
        return "Well, the first one wasn't quite a function."

This makes a class named function , and classes are callable, which is how we instantiate them. So the first call became an object instantiation and the second call calls an object. In this example, we don't actually have a function, though we do have two methods that are called within the two calls.

AChampion's example uses two normal function definitions, one of which occurs inside another creating a closure over that call's a value. That is a more traditional approach, though we can still muddle the waters using mutable values:

def function(a):
    def inner(b):
        return sum(a) == b
    return inner

>>> l = [1,2,3,4]
>>> eq = function(l)
>>> eq(10)
True
>>> eq(15)
False
>>> l.append(5)
>>> eq(15)
True
>>> eq(10)
False

We see here that this isn't a pure function in the mathematical sense, as its value is affected by other state than its arguments. We frequently try to avoid such side effects, or at least expose them by prominently displaying the state container, such as in method calls.

Lastly, depending on the context, the expression could fail in a variety of ways including NameError if function simply isn't defined, or TypeError if one of the calls was attempted on a non-callable object. It's still syntactically correct Python, and both of those exceptions are possible to handle, although doing so is likely a bit of a perversion. An example might be a spreadsheet program in which the cell formulae are Python expressions; you'd evaluate them with specific namespaces (globals), and catch any error to account for mistyped formulae.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM