当我想将它用于类的方法时,我如何在Python中编写一个装饰器,它有一些导入from Foo import Foo
,这也需要导入?
将导入放入两个单独的文件将导致错误,告诉我无法从Foo导入Foo。
如果不可能,那么: 如果装饰器不会在其他任何地方使用,将装饰器放入与类相同的文件中,这是一个好主意,这样我只需要编写一次导入,它就不会与任何其他导入冲突?
在我的实例中,我想编写一个装饰器,它只是更改一个标志,指示列表是否已更改。该类中修改列表的每个方法都将使用该装饰器进行修饰。
修改#1:
更改我的代码结构后,我现在只有两个参与的源代码文件。这些是:
# -*- coding: utf-8 -*-
from AppSettings import AppSettings
from FileManager import FileManager
from decorators.changesvocables import changesvocables
from exceptions.DuplicateVocableException import DuplicateVocableException
from exceptions.UnknownVocableException import UnknownVocableException
__author__ = 'xiaolong'
class VocableManager:
vocables = []
search_result = []
vocables_changed = False
test_counter = 0
test_call_counter = 0
def __init__(self):
pass
@classmethod
@changesvocables
def remove_vocable(cls, vocable):
VocableManager.test_call_counter += 1
if vocable in VocableManager.vocables:
VocableManager.test_counter += 1
VocableManager.vocables.remove(vocable)
# del vocable
else:
print(vocable)
raise UnknownVocableException('Vocable not found.')
# VocableManager.vocables_changed = True
@classmethod
@changesvocables
def remove_vocable_by_index(cls, index):
del VocableManager.vocables[index]
# VocableManager.vocables_changed = True
@classmethod
@changesvocables
def add_vocable(cls, vocable):
if vocable not in VocableManager.vocables:
VocableManager.vocables.append(vocable)
else:
raise DuplicateVocableException('The vocable already exists.')
# VocableManager.vocables_changed = True
之后,课程仍然继续,但没有其他方法changesvocables
装饰。如果需要,我可以添加整个班级。
装饰者:
# -*- coding: utf-8 -*-
from functools import wraps
from VocableManager import VocableManager as VocMan
__author__ = 'xiaolong'
def changesvocables(function):
@wraps(function)
def wrapper(*args, **kw):
result = function(*args, **kw)
VocMan.vocables_changed = True
return result
return wrapper
当我尝试运行应用程序时,这会导致以下错误:
** (__main__.py:16991): WARNING **: Couldn't connect to accessibility bus: Failed to connect to socket /tmp/dbus-sQwlsgyRi2: Connection refused
Traceback (most recent call last):
File "/home/xiaolong/development/pycharm-workspace/gtkplus-tool/gtkplustool/__main__.py", line 1, in <module>
from Application import Application
File "/home/xiaolong/development/pycharm-workspace/gtkplus-tool/gtkplustool/Application.py", line 8, in <module>
from VocableManager import VocableManager
File "/home/xiaolong/development/pycharm-workspace/gtkplus-tool/gtkplustool/VocableManager.py", line 4, in <module>
from decorators.changesvocables import changesvocables
File "/home/xiaolong/development/pycharm-workspace/gtkplus-tool/gtkplustool/decorators/changesvocables.py", line 3, in <module>
from VocableManager import VocableManager as VocMan
ImportError: cannot import name 'VocableManager'
修改#3:
这是一个MCVE:
main.py:
# -*- coding: utf-8 -*-
from mcve.ListManager import ListManager
__author__ = 'xiaolong'
if __name__ == '__main__':
list_manager = ListManager()
list_manager.add_item('item1')
装饰:
# -*- coding: utf-8 -*-
from functools import wraps
from mcve.ListManager import ListManager as ListMan
__author__ = 'xiaolong'
def changesitems(function):
@wraps(function)
def wrapper(*args, **kw):
result = function(*args, **kw)
ListMan.vocables_changed = True
return result
return wrapper
ListManager:
# -*- coding: utf-8 -*-
from mcve.changesitems import changesitems
class ListManager:
list_of_items = []
def __init__(self):
pass
@changesitems
def add_item(self, item):
if item not in ListManager.list_of_items:
ListManager.add_item(item)
与以前相同的错误:
Traceback (most recent call last):
File "/home/xiaolong/development/pycharm-workspace/MCVE/mcve/main.py", line 2, in <module>
from mcve.ListManager import ListManager
File "/home/xiaolong/development/pycharm-workspace/MCVE/mcve/ListManager.py", line 2, in <module>
from mcve.changesitems import changesitems
File "/home/xiaolong/development/pycharm-workspace/MCVE/mcve/changesitems.py", line 3, in <module>
from mcve.ListManager import ListManager as ListMan
ImportError: cannot import name 'ListManager'
Process finished with exit code 1
答案 0 :(得分:2)
尝试:
from Foo import Foo as foo
现在,您可以Foo
访问包,并以foo
访问装饰器。