如何在 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
之后类(class)仍然继续,但没有其他带有 changesvocables
装饰的方法。如果需要,我可以添加整个类(class)。
和装饰器:
# -*- 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
列表管理器:
# -*- 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
最佳答案
尝试:
from Foo import Foo as foo
现在您将可以访问包(如 Foo
)和装饰器(如 foo
)。
关于python - 如何编写与使用它的类具有相同导入的装饰器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32673239/