Python编译器函数在编译时调用

Dow*_*wie 6 python class decorator python-decorators

我希望熟悉Python的编译/运行时程序的人可以解释一下我关于Python如何编译装饰器函数的问题.

在我的示例代码中,我在定义logtofile闭包之前在"writeit"装饰器中包含了一个测试print语句.如果你运行我提供的整个代码,那么在使用writeit之前,为Customer类中定义的每个@writeit装饰器调用writeit中的"testing"print语句.

为什么在编译时调用logtofile?有人可以解释一下这种行为吗?

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()
Run Code Online (Sandbox Code Playgroud)

Mar*_*ers 7

您的代码在导入模块时运行.Python执行所有顶级语句,包括那时的类定义.

类定义体作为函数执行,本地命名空间成为类属性.这意味着类主体在导入时执行,前提是该类在模块的顶层定义.

当Python在执行时遇到一个装饰函数时,它将定义类,然后执行装饰器函数,传入函数对象并将装饰器的返回值绑定到函数的名称.由于类主体在导入期间执行,这意味着您的装饰器在此时执行.