Heim  >  Artikel  >  Backend-Entwicklung  >  Python-Dekoratoren

Python-Dekoratoren

巴扎黑
巴扎黑Original
2016-12-08 11:12:151244Durchsuche

Es gibt viele Möglichkeiten, einen benutzerdefinierten Dekorator zu schreiben. Die einfachste und am leichtesten zu verstehende Möglichkeit besteht jedoch darin, eine Funktion zu schreiben, die eine Unterfunktion zurückgibt, die den ursprünglichen Funktionsaufruf kapselt.

Das allgemeine Muster ist wie folgt.

Python-Code

def my_decorator(function):  
    def _my_decorator(*args, **kw):  
        #在调用实际函数之前做些填充工作  
        res = function(*args, **kw)  
        #做完某些填充工作之后  
        return res  
    #返回子函数  
    return _my_decorator


Wenn der Dekorateur Parameter benötigt, muss er die zweite Verpackungsebene verwenden.

Python-Code

def my_decorator(arg1, arg2):  
    def _my_decorator(function):  
        def __my_decorator(*args, **kw):  
            res = function()  
            return res  
        return __my_decorator  
    return _my_decorator


bezieht sich auf

, da der Dekorator beim ersten Lesen des Moduls als Programm interpretiert wird geladen, daher muss ihre Verwendung auf die insgesamt anwendbaren Wrapper beschränkt werden. Wenn ein Dekorator an die Klassen- oder erweiterte Funktionssignatur einer Methode gebunden ist, sollte er in ein reguläres aufrufbares Objekt umgestaltet werden, um Komplexität zu vermeiden. Wenn Dekorateure mit APIs umgehen, ist es auf jeden Fall ein guter Ansatz, sie in einem leicht zu wartenden Modul zusammenzufassen.


Parameterprüfung:

Python-Code

def check_param_isvalid():  
    def check(method):  
        def check_param(*args,**kwargs):  
            for a in args:  
                assert isinstance(a, int),"arg %r does not match %s" % (a,int)  
                assert a > 100000,"arg %r must gt 100000" % a  
            return method(*args, **kwargs)  
        return check_param  
    return check  
 
@check_param_isvalid()  
def foo(*args):  
    print args  
  
foo(200000,500000)


Caching:

Python-Code

import time  
import hashlib  
import pickle  
  
cache = {}  
def is_obsolete(entry, duration):  
    return time.time() - entry['time'] > duration  
  
def computer_key(function, args, kw):  
    key = pickle.dumps((function.func_name, args, kw))  
    return hashlib.sha1(key).hexdigest()  
  
def memoize(duration=30):  
    def _memoize(function):  
        def __memoize(*args, **kw):  
            key = computer_key(function, args, kw)  
            if key in cache and not is_obsolete(cache[key], duration):  
                print 'wo got a winner'  
                return cache[key]['value']  
            result = function(*args, **kw)  
            cache[key] = {'value':result,'time':time.time()}  
            return result  
        return __memoize  
    return _memoize  
 
@memoize()  
def very_complex_stuff(a,b):  
    return a + b  
  
print very_complex_stuff(2,2)



Agent:

Python-Code

class User(object):  
    def __init__(self, roles):  
        self.roles = roles  
  
class Unauthorized(Exception):  
    pass  
  
def protect(role):  
    def _protect(function):  
        def __protect(*args, **kw):  
            user = globals().get('user')  
            if user is None or role not in user.roles:  
                raise Unauthorized("I won't tell you")  
            return function(*args, **kw)  
        return __protect  
    return _protect  
  
tarek = User(('admin', 'user'))  
bill = User(('user',))  
  
class MySecrets(object):  
 
    @protect('admin')  
    def waffle_recipe(self):  
        print 'use tons of butter!'  
  
these_are = MySecrets()  
user = tarek  
these_are.waffle_recipe()  
user = bill  
these_are.waffle_recipe()


Kontextanbieter:

Python-Code

from threading import RLock  
lock = RLock()  
  
def synchronized(function):  
    def _synchronized(*args, **kw):  
        lock.acquire()  
        try:  
            return function(*args, **kw)  
        finally:  
            lock.release()  
    return _synchronized  
 
@synchronized  
def thread_safe():  
    print 'haha'  
     
thread_safe()


Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn