KDTTAH #1: decorator magic

  1. От една страна, не е твърде трудно да се съобрази, че това, което се подава на един декоратор, съвсем не е нужно да бъде функция:

    def snoop(func):
       
    def snooping(*args, **kwargs):
           
    print("Now look who's {0}ing with {1} and {2}!".format(func.__name__, args, kwargs))
           
    return func(*args, **kwargs)
       
    return snooping

    @snoop
    def add(x, y): return x + y

    @snoop
    class hushhush:
       
    def __init__(self, secret):
           
    print("No one knows that we are hush-hushing, right?")
           
    self._secret = secret
       
    def tellmetellmetellme(self):
           
    return self._secret

    А като се замислиш, това може да доведе до... забавни ефекти :)

    def evil(func):
       
    def returnnone(*args, **kwargs):
           
    print('Ia!  Ia!  Shub-Niggurath!')
           
    return None
       
    return returnnone

    @evil
    class victim:
       
    def __init__(self, foo):
           
    print('Initializing a', self.__class__.__name__, 'object with', foo)
           
    self._something = foo
       
    def __call__(self):
           
    return self._something

    А кой питаше за това дали един декоратор може да бъде приложен към самия себе си? :)

    def muenchhausen(func):
       
    print('Trying to pull', func.__name__, 'out by its hair...')
       
    return func(func)

    @muenchhausen
    def improve(func):
       
    def improved(*args, **kwargs):
           
    print("Hey now, don't you just love the new and improved {0}!".format(func.__name__))
           
    return func(*args, **kwargs)
       
    print('Improving', func.__name__)
       
    return improved

    Но, както си пише и в заглавието на темата, не опитвайте това вкъщи!... а на работа - още по-малко! :P

    ...а може би е добре да си лягам да спя, преди да ми е хрумнала още някоя простотия...

    Публикувано преди
  2. Мняяяяяя, не се получи това със заспиването веднага и това си е - просто преди да изключа компютъра успя да ми хрумне още една простотия :)

    def snoop(func):
       
    def snooping(*args, **kwargs):
           
    print("Now look who's {0}ing with {1} and {2}!".format(func.__name__, args, kwargs))
           
    return func(*args, **kwargs)
       
    print('Trying to snoop on', func, 'of class', func.__class__.__name__)
       
    if func.__class__.__name__ == 'type':
           
    print("Whee, it's a class!")
           
    for (name, value) in func.__dict__.items():
               
    print('- class', func.__name__, '- examining', name, 'of type', value.__class__.__name__)
               
    if value.__class__.__name__ == 'function':
                   
    print('- class', func.__name__, '- need to replace', name)
                    func
    .__class__.__setattr__(func, name, snoop(value))
       
    return snooping

    Естествено, опитах да го направя напълно - с if value.__class__.__name__ in ('function', type') :) Е, оказа се, че е проблем, когато в класа, върху който snoop–вам, има дефинирани подкласове - те биват заместени с функции и съответно опита да инстанциирам обект от този тип (опит, който snoop-ваният клас си прави, без да знае, че някой го snoop-ва), не минава съвсем. Разбира се, досещам се, че това вероятно може да се оправи, като самият декоратор snoop не е функция, а клас, който използва още един-два магически метода... но с любимата ми реплика на Скарлет О'Хара, "за това ще мисля утре!"

    Публикувано преди

Трябва да сте влезли в системата, за да може да отговаряте на теми.