mardi 23 mai 2023

Are classic and dynamic decorators limited to only the way they are applied or extend to functionality differences as well?

I am pretty new here and have been reading about Python Decorators and came across 2 types of decorator patterns.

  1. Classic Decorators
  2. Dynamic Decorators

What I understood as the difference between the two is, Classic decorators do not allow access to underlying object attributes. Now while the text part is understood, I wrote a code to see it for myself and I am unable to determine the category of decorator used in the example.

As for me, from my experiments and trials, I can change the attributes and see them reflected as well.

Code that I wrote to demonstrate this, is as below.

from dataclasses import dataclass, field
import random
import string
import time

def timeit(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        ret = func(*args, **kwargs)
        stop = time.time()
        print(f'>>> Total time taken : {int((stop-start)*1000)}ms')
        return ret
    return wrapper

def generate_id(classname):
        return classname.upper() + "".join(random.choices(string.ascii_uppercase, k=12))

@dataclass
class Person:
    name: str
    email: str
    address: str
    age: int
    id: str = field(init=False) #, default_factory=generate_id)
    _search_string: str = field(init=False, repr=False)

    def __post_init__(self) -> None:
        print(f'{type(self).__name__}')
        self.id = generate_id(classname=f'{type(self).__name__}')
        self._search_string = f'{self.name} {self.address}'
        time.sleep(1)

    def __str__(self) -> str:
        print(f'{type(self).__name__}')
        return f'{self.name} lives in {self.address}'

@timeit
def main() -> None:
    person = Person(name="Amitabh", email="amitabh@ainebula.in", address="India", age=31)
    print(person)
    print(repr(person))
    person.address = "Bangalore, India"
    print("After change")
    print(person)
    print(repr(person))

if __name__ == '__main__':
    main()

When I execute the program, the output of this program is as below. As you can see that when I changed the attribute, the change reflect well. What is the key point I am missing here? Any pointers?

Person
Person
Amitabh lives in India
Person(name='Amitabh', email='amitabh@ainebula.in', address='India', age=31, id='PERSONDUQLSUAGCJJJ')
After change
Person
Amitabh lives in Bangalore, India
Person(name='Amitabh', email='amitabh@ainebula.in', address='Bangalore, India', age=31, id='PERSONDUQLSUAGCJJJ')
>>> Total time taken : 1004ms

If anyone of you need more details on the question, kindly comment and I shall provide more info. As on now, this is the best I could frame my question.

If this does not follow the Classic Decorator pattern, I want to know how and why.

Aucun commentaire:

Enregistrer un commentaire