# I. nonlocal keyword

```def outer():
num = 0
def inner():
# If you want to modify the value of an external function variable (name) in a nested function
nonlocal num  # Unify the names of L and E (the names in e need to be defined in advance)
num = 10
print(num) # 10
inner()
print(num)  # 10
outer()
print(num)  # name 'num' is not defined```

# II. Decorator

### Definition:

The essence of function is to add functions to other functions.

### Open and closed principle:

1. The source code of the decorated function cannot be modified

2. The calling method of the decorated function cannot be modified

### Understand the knowledge reserve of decorators:

1. Function is variable

2. Higher order function

3. Nested function

### Higher order function + nested function = = decorator

Higher order function: the variable can point to the function, the parameter of the function can receive the variable, then one function can receive another function as the parameter, which is the higher order function.

#1. Pass a function name as an argument to another function (add function without modifying the source code of the decorated function)

#2. The return value contains the function name (the calling method of the function is not modified)

Examples of higher-order functions:

```def add(x,y,f):
return f(x)+f(y)
print(res)```

### Decoration method:

```def wrap(fn):
def inner(*args,**kwargs):
print("Pre increasing function")
result = fn(*args,**kwargs)
print("Post increment function")
return result
return inner

@wrap
def fn1():
print("fn1 Original function of")
@wrap
def fn2(a,b):
print("fn2 Original function of")
@wrap
def fn3():
print("fn3 Original function of")
return True
@wrap
def fn4(a,*,x):
print("fn4 Original function of")
return True

fn1()
fn2(10,20)
fn3()
fn4(10,x=20)
```

### Decorator demonstration:

```import time
def timmer(func):
def warpper(*args,**kwargs):
start_time=time.time()
func()
stop_time=time.time()
print('the func run time is %s'%(stop_time-start_time))
return warpper()

@timmer   #Grammatical sugar
def test1():
time.sleep(3)
print('in the test1')
test1()```

### Examples of function decorators with parameters and returns:

```# Add an account processing function: 3 or more English letters or Chinese characters
def check_usr(fn):
def inner(usr,pwd):
if not (len(usr) >= 3 and usr.isalpha()):
print("Account verification failed")
return False
result = fn(usr,pwd)  # login
return result
return inner

# Add a password processing function: 6 or more English and numbers
def check_pwd(fn):
def inner(usr,pwd):
if not (len(pwd) >= 6 and pwd.isalnum()):
return False
return fn(usr,pwd)
return inner

@check_usr
@check_pwd
if usr == 'abc' and pwd == '123qwe':
print("Landing successfully")
return True
return False

res = login('abc','123qwe')  # inner
print(res)

#summary
1,login There are parameters, so inner And fn All have the same parameters
2,login There is a return value, so inner And fn All have return values```

### Decorator with variable length parameter

```def wrap(fn):
def inner(*args,**kwargs):
result = fn(*args,**kwargs)
print("New function")
return result
return inner

@wrap
def func(a,b,c,*,x,y,z):
print(a,b,c,x,y,z)
print("Original function")

func(1,2,3,x=10,y=20,z=30)```

### Decorator with reference

```def outer(input_color):
def wrap(fn):
if input_color == 'red':
info = '\033[31mnew action\033[0m'
else:
info = '\033[32mGreen:new action\033[0m'
def inner(*args,**kwargs):
result = fn(*args,**kwargs)
print(info)
return result
return inner
return wrap   # outer(color) --> wrap

color = input("color:")
@outer(color)
def func():
print('func run')

func()```

### Login authentication case:

```is_login = False  # Landing status

usr = input("usr:")
if not (len(usr) >= 3 and usr.isalpha()):
print('Account verification failed')
return False
pwd = input("pwd:")
if usr == 'abc' and pwd == '123qwe':
else:

# Finish a decorator of login status verification
def inner(*args,**kwargs):
if is_login != True:
print("You are not logged in.")
result = fn(*args,**kwargs)
return result
return inner

def home():
print("Personal homepage")

#Sales function
def sale():
print("Can sell")

home()
sale()```

### Decorator case advanced:

```import time
user,passwd = 'shj','abc123'
def auth(auth_type):
print("auth func:",auth_type)
def outer_wrapper(func):
def wrapper(*args,**kwargs):
print("wrapper func args:",*args,**kwargs)
if auth_type == 'local':
print("User has passed authentication")
res = func(*args,**kwargs)
print("-------after authentication")
return res
else:
elif auth_type == 'ldap':
print("It is so difficult !")
return wrapper
return outer_wrapper
def index():
print("welcome to index page")
@auth(auth_type="local")  #Equivalent to home = wrapper()
def home():
@auth(auth_type="ldap")
def bbs():
print("welcome to bbs page")

index()
home()
bbs()
```

Tags: Programming

Posted on Mon, 02 Dec 2019 10:38:09 -0500 by crazytoon