Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:装饰器、作用域和模块导入_Python_Python Decorators - Fatal编程技术网

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

Python:装饰器、作用域和模块导入,python,python-decorators,Python,Python Decorators,因此,我正在尝试学习使用Python(2.x)装饰器,在与它们打交道时,我遇到了……一件奇怪的事情。总而言之,我想我正在尝试使用装饰器将装饰后的函数添加到其他地方的存储中 我不知道这是否是做任何事情的最具python风格的方式,但我想了解出了什么问题 假设我有一个模块(作为脚本运行),如下所示: # -*- coding: utf-8 -*- # main.py d = {} b = [] def mydecorator(name): b.append(name) def de

因此,我正在尝试学习使用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']
并将其导入到
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()
列表和dict中的更改不会持续:

and here {} ['boo']
in here {'boo': <function not_workin_func at 0x7fd1009917d0>} ['boo']
out there {} []
这里是{}['boo']
在这里{'boo':}['boo']
外面{}[]

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

问题在于循环导入,在初始化
模块后,字典
d
和列表
b
将被替换为空列表

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

module.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
main.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 {} []
main-导入模块
模块初始化
模块-从主服务器导入
主-导入模块
主-使空d,b
主-定义mydecorator
main-定义main
模块定义类
这里是{}['boo']
在这里{'boo':}['boo']
主-使空d,b
主-定义mydecorator
main-定义main
干管-运行干管
外面{}[]
您可以看到,在类定义中应用decorator之后,
d
b
被重新分配到空列表和字典


老实说,除了将decorator和
d
b
从main移到自己的模块中以解决循环依赖性之外,我不太明白如何解决这个问题,但我认为大多数人都会同意,应尽可能避免循环导入,如果不是严格禁止的话。

您有一个循环导入,这使得事情很难推理-请尝试将mydecorator从
main.py
移动到
module.py
或其他模块中。谢谢,将所有decorator内容移动到其他模块中是可行的(从这个意义上讲,如果我在
main.py
中导入
b
d
,它们的内容确实与第一种情况相同)。那么,主要问题是循环导入?
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 {} []