Python advanced Adorner 2. Defines an adorner that can accept parameters, defines an adorner that can be modified by the user, and defines an adorner that accepts optional parameters

Source: Internet
Author: User

2.1. Define an adorner that accepts parameters

In understanding the previous article, we understand the idea of defining an adorner that accepts parameters.

Idea: Define a function that takes parameters in the outer layer of the adorner function, and let him return to the adorner function and manipulate the relevant parameters in the adorner function.

The code resolves as follows:

From Functools Import Wraps
Import logging
# define the outer function logged, return the adorner function with return decorate
def logged (level, Name=none, Message=none):
"""
ADD logging to a function. Level is the logging
Level, name was the logger name, and message is the
Log message. If name and message aren ' t specified,
They default to the function ' s module and name.
"""
# define an adorner that returns the wrapper function
def decorate (func):
# related actions to incoming parameters
logname = Name If name Else func.__module__
Print (LOGNAME)
Log = Logging.getlogger (logname)
Print (log)
LOGMSG = message if message else func.__name__
Print (LOGMSG)

@wraps (func)
# define the wrapper function, return the decorated Func function, i.e. the add function or the spam function in the following example
def wrapper (*args, **kwargs):
Log.log (level, logmsg)
return func (*args, **kwargs)
Return wrapper
Return decorate

# Example Use
@logged (logging. DEBUG)
def add (x, y):
return x + y

Print (Add (2,5))

Output:

__main__
<logger __main__ (WARNING) >
Add
7



@logged (logging. CRITICAL, ' example ')
def spam ():
Print (' spam! ')

Print (spam ())
Output:

Example
<logger Example (WARNING) >
Spam
spam!

None #若def函数后面追加一个return "Hello", then the last none is changed to Hello

Summary:

@decorator(xyz)func(abpass       

The adorner process is equivalent to the following call;

Func(abpassdecorator(xyz) (func)    

2.2 How to define an adorner that a property can be modified by the user

Preface: Define an adorner that can pass parameters, if you need to change the properties of the adorner dynamically, how to define it?

Idea: Use accessor functions here (accessor function) and then nonlocal modify the internal variables

The code resolves as follows:

 fromFunctoolsImportWraps, PartialImportLogging#Utility decorator to attach a function as an attribute of objdefAttach_wrapper (obj, func=None):ifFunc isNone:returnpartial (Attach_wrapper, obj) setattr (obj, func.__name__, func)returnfuncdefLogged (level, Name=none, message=None):" "ADD logging to a function. The logging level, name is the logger name, and message is the log Messa Ge.    If name and message aren ' t specified, they default to the function ' s module and name. " "    defDecorate (func): LogName= NameifNameElseFunc.__module__Log=Logging.getlogger (logname) logmsg= MessageifMessageElseFunc.__name__@wraps (func)defWrapper (*args, * *Kwargs): Log.log (level, logmsg)returnFunc (*args, * *Kwargs)#Attach Setter Functions@attach_wrapper (wrapper)defSet_level (newlevel): nonlocal level level=newlevel @attach_wrapper (wrapper)defset_message (newmsg): nonlocal logmsg logmsg=newmsgreturnwrapperreturnDecorate#Example Use@logged (logging. DEBUG)defAdd (x, y):returnX +y@logged (logging. CRITICAL,'Example')defspam ():Print('spam!')#level is set to debug by defaultLogging.basicconfig (level=logging. DEBUG)Print(Add (2, 3))#Debug:__main__:add#5#Change the log messageAdd.set_message ('Add called')Print(Add (2, 3))#Debug:__main__:add called#5#Change the log levelAdd.set_level (logging. WARNING)Print(Add (2, 3))#Warning:__main__:add called#5


If you use other methods for direct access to properties, you can only access the top level adorner, for example:
@timethis@logged(logging.  DEBUG)Countdown(n01          
Where the top-level adorner function is:@timethis, the method of directly accessing the property will fail, please remember this

The content of this section can be used as an alternative to subsequent class adorners

Python advanced Adorner 2. Defines an adorner that can accept parameters, defines an adorner that can be modified by the user, and defines an adorner that accepts optional parameters

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.