gpt4 book ai didi

Python:装饰器、作用域和模块导入

转载 作者:太空宇宙 更新时间:2023-11-04 05:50:29 25 4
gpt4 key购买 nike

因此,我正在尝试学习使用 Python (2.x) 装饰器,在与它们打交道时,我遇到了……一件奇怪的事情。总而言之,我想我正在尝试使用装饰器将装饰函数添加到其他地方的存储中。

我不知道这是否是最符合 Python 风格的做事方式,但我想了解出了什么问题。

假设我有一个像这样的模块(作为脚本运行):

# -*- coding: utf-8 -*-
# main.py

d = {}
b = []
def mydecorator(name):
b.append(name)
def decorator(fun):
d[name] = fun
print 'in here', d, b
return fun
print 'and here', d, b
return decorator

class SomeClass:
@mydecorator('a thing')
def working_func(self, params):
# do stuff
pass

def main():
# do stuff
print 'out there', d, b


if __name__ == '__main__':
main()

按预期打印:

and here {} ['a thing']
in here {'a thing': <function working_func at 0x7fd6b69e0758>} ['a thing']
out there {'a thing': <function working_func at 0x7fd6b69e0758>} ['a thing']

但是,如果我将类移动到一个单独的模块中

# -*- coding: utf-8 -*-
# module.py

from main import mydecorator

class AnotherClass:
@mydecorator('boo')
def not_workin_func(self, params):
# do stuff
pass

并将其导入main.py

# -*- coding: utf-8 -*-
# main.py
import module

d = {}
b = []
def mydecorator(name):
b.append(name)
def decorator(fun):
d[name] = fun
print 'in here', d, b
return fun
print 'and here', d, b
return decorator

def main():
# do stuff
print 'out there', d, b


if __name__ == '__main__':
main()

列表和字典中的更改不会持久化:

and here {} ['boo']
in here {'boo': <function not_workin_func at 0x7fd1009917d0>} ['boo']
out there {} []

我想这与 python 如何处理作用域/模块导入有关?

最佳答案

问题是循环导入,字典 d 和列表 bmodule 初始化后被替换为空列表。

你可以通过添加一些打印语句来查看执行顺序:

模块.py:

# -*- coding: utf-8 -*-
# module.py
print(' module - init')

print(' module - importing from main')
from main import mydecorator
#import main


print(' module - definiting class')
class AnotherClass:
@mydecorator('boo')
def not_workin_func(self, params):
# do stuff
pass

主要.py:

# -*- coding: utf-8 -*-
# main.py

print('main - importing module')
import module

print('main - making empty d,b')
d = {}
b = []

print('main - definiting mydecorator')
def mydecorator(name):
b.append(name)
def decorator(fun):
d[name] = fun
print 'in here', d, b
return fun
print 'and here', d, b
return decorator

print('main - defining main')
def main():
# do stuff
print 'out there', d, b

if __name__ == '__main__':
print('main - running main')
main()

现在,当您运行 python main.py 时,您可以看到按什么顺序发生了什么:

main - importing module
module - init
module - importing from main
main - importing module
main - making empty d,b
main - definiting mydecorator
main - defining main
module - definiting class
and here {} ['boo']
in here {'boo': <function not_workin_func at 0x100ca4aa0>} ['boo']
main - making empty d,b
main - definiting mydecorator
main - defining main
main - running main
out there {} []

您可以看到 db 在类定义中应用装饰器之后 被重新分配给空列表和字典。 p>

老实说,除了将装饰器和 db 从 main 移到它自己的模块中以解决这个问题,我真的不知道如何解决这个问题循环依赖,但我认为大多数人会同意,即使不严格禁止,也应尽可能避免循环导入。

关于Python:装饰器、作用域和模块导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30512766/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com