You can use def to define a function in Python. Every function is an instance of function, so it can be assigned to other variables. For example:

```
def max(m, n):
return m if m > n else n
print(max(10, 3)) # print 10
maximum = max
print(maximum(10, 3)) # print 10
```

If you want to create an anonymous function in Python, you can use a lambda expression. For example:

```
max = lambda m, n: m if m > n else n
print(max(10, 3)) # print 10
```

Different languages provide function/lambda supports with different syntax. Python's clean syntax looks better to express a function than JavaScript. You can see the cleanness difference in the following examples:

**// Define a function: JavaScript**

**function max(n, n) {**

**return m > n ? m : n;**

**}**

**# Define a function: Python**

**def max(m, n):**

**return m if m > n else n**

**// Create an anonymous function: JavaScript**

**function(n, n) {**

**return m > n ? m : n;**

**};**

**# Create an anonymous function: Python**

**lambda m, n: m if m > n else n**

Let's see another use of lambda/closure. If your function needs a time-consuming resource, reusing it to avoid performance issues is often a consideration. One of the ways is to create the resource globally and reuse it in the function. A global resource, however, is often a bad practice. We can prepare the resource in a function, create a closure to catch it, and return the closure from that function. For example:

```
import math
def prepare_factor(max):
# Creating a prime table is time-consuming.
```** ****primes**** = [i for i in range(2, max) if prime[i] == 1]**
def factor(num):
while **primes**[i] ** 2 <= num:
if num % **primes**[i] == 0:
list.append(**primes[i]**)
num //= **primes**[i]
else:
i += 1
return **factor**
factor = prepare_factor(1000)
print(factor(100)) # print [2, 2, 5, 5]

In the above example, the inner function factor creates a closure to catch the primes variable of the enclosing function. Because a function is an object, you can return it from a function. The lifecycle of the primes variable is now associated with the returned function. We don't expose the primes variable globally, yet still can reuse the resource.

Until now, we've seen that, when a function is an object, it can be...

- Referred by other variables.
- Not only called, but also passed into a function to replace the algorithm in a reusable template.
- A closure to catch free variables (resource) and returned from a function.

```
def func():
x = 10
def getX():
return x
def setX(n):
```**x = n # Create a local variable x**
return (gegX, setX)
getX, setX = func()
getX() # 10
setX(20)
getX(10) # still 10

In Python, the first time when you assign to a variable, you create a new local variable. In the above example, when you call setX, you actually create a local variable x in setX, not assign the parameter n to the local variable of func. That's why you get 10 in the last statement.

Fortunately, after Python 3, you can use the global or nonlocal keywords to avoid this condition. For example:

```
def func():
x = 10
def getX():
return x
def setX(n):
nonlocal x = n
return (gegX, setX)
getX, setX = func()
getX() # 10
setX(20)
getX(10) # 20
```

In the above example, the nonlocal keyword says x is not a local variable. The Python interpreter looks the enclosing function and understands x is caught from the local variable x of func. This time when you call setX, you definitely change the value of the local variable x in func.

We've talked about lambda/closure supports in JavaScript and Python. They are both dynamically-typed languages. If we move into statically-typed languages, however, what issues should we concern? Looking at a statically-typed language with lambda/closure supports to learn some experience seems a good idea. That's we'll talk about Scala in the next article.