我希望熟悉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()
答案 0 :(得分:6)
当模块导入时,您的代码会运行。 Python执行所有顶级语句,包括那时的类定义。
类定义体作为函数执行,本地命名空间成为类属性。这意味着类主体在导入时执行,前提是该类在模块的顶层定义。
当Python在执行时遇到装饰函数时,它将定义类,然后执行装饰器函数,传入函数对象并将装饰器的返回值绑定到函数的名称。由于类主体在导入期间执行,这意味着您的装饰器在此时执行。
答案 1 :(得分:1)
没有编译时间。 def
语句和关联的装饰器调用是可执行语句。
因此,当Python加载模块时,它会按顺序执行语句。执行类语句时,其中一个早期阶段是执行类主体中的所有语句。作为def
的一部分运行以创建函数,这些函数对象将被传递给装饰器进行处理。
只要调用装饰器,就会运行“testing”print语句,而不是在调用它返回的函数时运行。如果您想要该行为,请将装饰器移动到内部函数中。