Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python decorator function called at compile time

I hope that someone familiar with Python's compilation / run-time procedures could shed some light on my question relating to how Python compiles decorator functions.

Within my sample code, I've included a testing print statement in the "writeit" decorator just before the logtofile closure is defined. If you run the entire code that I've provided, the "testing" print statement in writeit is called for each @writeit decorator defined in the Customer class-- before writeit is ever used.

Why is logtofile being called at compile time? Could someone please explain this behavior?

def writeit(func): 
    print('testing')

    def logtofile(customer, *arg, **kwargs):
        print('logtofile')
        result = func(customer, *arg, **kwargs)        
        with open('dictlog.txt','w') as myfile:
            myfile.write(func.__name__)
        return result

    return logtofile

class Customer(object):
    def __init__(self,firstname,lastname,address,city,state,zipcode):        
        self._custinfo = dict(firstname=firstname,lastname=lastname,address=address,city=city,state=state,zipcode=zipcode)        

    @writeit
    def setFirstName(self,firstname):
        print('setFirstName')
        self._custinfo['firstname']=firstname

    @writeit
    def setLastName(self,lastname):
        print('setLastName')
        self._custinfo['lastname']=lastname

    @writeit
    def setAddress(self,address):
        print('setAddress')
        self._custinfo['address']=address

def main():
    cust1 = Customer('Joe','Shmoe','123 Washington','Washington DC','DC','12345')
    cust1.setFirstName('Joseph')
    cust1.setLastName('Shmoestein')

if(__name__ == '__main__'): main()
like image 278
Dowwie Avatar asked Aug 05 '13 15:08

Dowwie


People also ask

What is true about decorators in Python?

Decorators are a very powerful and useful tool in Python since it allows programmers to modify the behaviour of a function or class. Decorators allow us to wrap another function in order to extend the behaviour of the wrapped function, without permanently modifying it.

What order are Python decorators called?

Bottom to top (inside-out) order: Multiple Decorators for python functions.

How do function decorators work in Python?

Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated. Using decorators in Python also ensures that your code is DRY(Don't Repeat Yourself).

Is decorator can be chained?

Chaining decorators means applying more than one decorator inside a function. Python allows us to implement more than one decorator to a function. It makes decorators useful for reusable building blocks as it accumulates several effects together. It is also known as nested decorators in Python.


1 Answers

Your code runs when the module is imported. Python executes all top-level statements, including class definitions at that time.

A class definition body is executed as a function, with the local namespace becoming the class attributes. This means that class bodies are executed on import, provided the class is defined at the top-level of the module.

When Python encounters a decorated function when executing, it'll define the class, then execute the decorator function, passing in the function object and binding the return value of the decorator to the name of the function. Since the class body is executed during import, this means your decorator is executed at that time.

like image 192
Martijn Pieters Avatar answered Oct 27 '22 09:10

Martijn Pieters