程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python Advanced Series (4)

編輯:Python

Catalog

Returns a function from a function

Pass a function as an argument to another function

Your first decorator


Returns a function from a function

You don't have to execute another function in one function , We can also return it as output :

def hi(name="yasoob"):
    def greet():
        return "now you are in the greet() function"
    def welcome():
        return "now you are in the welcome() function"
    if name == "yasoob":
        return greet
    else:
        return welcome
a = hi()
print(a)
#outputs: <function greet at 0x7f2143c01500>
# It clearly shows `a` Now point to hi() Function greet() function
# Now try this
print(a())
#outputs: now you are in the greet() function

Look at this code again . stay if/else In statement we return greet and welcome, instead of greet() and welcome(). Why is that ? This is because when you put a pair of parentheses at the end , This function will execute ; However, if you don't put the parentheses after it , Then it can be passed around , And you can assign values to other variables without executing them .

Do you understand ? Let me explain a little more details .

When we write down a = hi(),hi() Will be performed , And because the name The default parameter is yasoob, So letter

Count greet Be returned to the . If we change the statement to a = hi(name = "ali"), that welcome The function will be returned . We can also print it out hi()(), This output now you are in the greet() function.

Pass a function as an argument to another function

def hi():
    return "hi yasoob!"
def doSomethingBeforeHi(func):
    print("I am doing some boring work before executing hi()")
    print(func())
doSomethingBeforeHi(hi)
#outputs:I am doing some boring work before executing hi()
#        hi yasoob!

Now you have all the necessary knowledge , To learn more about what a decorator really is . Decorators let you execute code before and after a function .

Your first decorator

In the last example , In fact, we have created a decorator ! Now let's modify the next decorator , And write a slightly more useful program :

def a_new_decorator(a_func):
    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()"       
        a_func()       
        print("I am doing some boring work after executing a_func()"
   
    return wrapTheFunction
def a_function_requiring_decoration():
    print("I am the function which needs some decoration to remove my foul smell")
a_function_requiring_decoration()
#outputs: "I am the function which needs some decoration to remove my foul smell
a_function_requiring_decoration=a_new_decorator(a_function_requiring_decoration)
#now a_function_requiring_decoration is wrapped by wrapTheFunction()
a_function_requiring_decoration()
#outputs:I am doing some boring work before executing a_func()
#        I am the function which needs some decoration to remove my foul smell
#        I am doing some boring work after executing a_func()

Do you understand ? We just applied the principles we learned before . That's exactly what it is. python What the decorator does ! They encapsulate a function , And modify its behavior in one way or another . Now you may wonder , We don't use... In the code @ Symbol ? That's just a short way to generate a decorated function . Here's how we use @ To run the previous code :


@a_new_decorator
def a_function_requiring_decoration():
    """Hey you! Decorate me!"""
    print("I am the function which needs some decoration to remove my foul smell")
a_function_requiring_decoration()
#outputs: I am doing some boring work before executing a_func()
#         I am the function which needs some decoration to remove my foul smell
#         I am doing some boring work after executing a_func()
#the @a_new_decorator is just a short way of saying:
a_function_requiring_decoration=a_new_decorator(a_function_requiring_decoration)

I hope you are right now Python There is a basic understanding of the working principle of the decorator . If we run the following code, there will be a problem :


print(a_function_requiring_decoration.__name__)
# Output: wrapTheFunction

That's not what we want !Ouput The output should be “a_function_requiring_decoration”. The function here is defined by warpTheFunction Replaced the . It overrides the name and comment documentation of our function (docstring). Fortunately, Python Give us a simple function to solve this problem , That's it functools.wraps. Let's modify the previous example to use it

functools.wraps:
from functools import wraps
def a_new_decorator(a_func):
    @wraps(a_func)
    def wrapTheFunction():
        print("I am doing some boring work before executing a_func()"
        a_func()
        print("I am doing some boring work after executing a_func()"
    return wrapTheFunction
@a_new_decorator
def a_function_requiring_decoration():
    """Hey yo! Decorate me!"""
    print("I am the function which needs some decoration to remove my foul smell")
print(a_function_requiring_decoration.__name__)
# Output: a_function_requiring_decoration

It's much better now . Let's learn some common scenes of decorators .

Blueprint specification :


from functools import wraps
def decorator_name(f):
    @wraps(f)
    def decorated(*args, **kwargs):
        if not can_run:
            return "Function will not run"
        return f(*args, **kwargs)
    return decorated
@decorator_name
def func():
    return("Function is running")
can_run = True
print(func())
# Output: Function is running
can_run = False
print(func())
# Output: Function will not run

Be careful :@wraps Accept a function to decorate , And added the copy function name 、 Annotation document 、 Parameter list and so on . This allows us to access the properties of the function before the decoration in the decorator .


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved