上下文管理器定义错误
Error with context manager definition
我有以下 Python 脚本:
from contextlib import contextmanager
@contextmanager
def my_content_manager():
self.entrance = True
try:
yield
except Exception as ex:
self.entrance = False
with my_content_manager() as cm:
print (cm.entrance)
print (cm.entrance)
当我尝试 运行 脚本时,我得到以下信息:
Traceback (most recent call last):
File "test.py", line 12, in <module>
with my_content_manager() as cm:
File "C:\Users\abc\AppData\Local\Programs\Python\Python36\lib\contextlib.py", line 82, in __enter__
return next(self.gen)
File "test.py", line 5, in my_content_manager
self.entrance = True
NameError: name 'self' is not defined
这是为什么?我该如何解决这个错误?
谢谢。
错误 NameError: name 'self' is not defined
是不言自明的,没有双关语的意思。 self
只是 classes 方法中约定使用的名称。您没有在任何地方定义 self
,所以 Python 不知道该怎么做。此外,您已经定义了一个函数,而不是 class 中的方法,因此这离工作还很远。使用 class 来定义上下文管理器,如下所示:
class MyContextManager(object):
def __init__(self):
self.entrance = True
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_val:
self.entrance = False
# signal that the exception was handled and the program should continue
return True
with MyContextManager() as cm:
print (cm.entrance)
raise Exception()
print (cm.entrance)
编辑:如果按照评论中的要求,您只想打印一个值而不是将其存储在某处:
@contextmanager
def my_content_manager():
try:
yield
except Exception as ex:
print(False)
else:
print(True)
一般来说,使用 class 可能是更好的方法(正如其他答案所暗示的那样)。但是,我记得函数对象可以有属性。我遇到了 this 相关问题,这导致了以下技巧(这看起来确实是对该功能的滥用):
from contextlib import contextmanager
@contextmanager
def my_content_manager():
my_content_manager.entrance = True
try:
yield my_content_manager.entrance
finally:
my_content_manager.entrance = False
my_content_manager.entrance = False
with my_content_manager() as cm:
print(my_content_manager.entrance)
# Or, print(cm)
print(my_content_manager.entrance)
此技术可能存在缺陷。我只是出于好奇而发布它。
我有以下 Python 脚本:
from contextlib import contextmanager
@contextmanager
def my_content_manager():
self.entrance = True
try:
yield
except Exception as ex:
self.entrance = False
with my_content_manager() as cm:
print (cm.entrance)
print (cm.entrance)
当我尝试 运行 脚本时,我得到以下信息:
Traceback (most recent call last):
File "test.py", line 12, in <module>
with my_content_manager() as cm:
File "C:\Users\abc\AppData\Local\Programs\Python\Python36\lib\contextlib.py", line 82, in __enter__
return next(self.gen)
File "test.py", line 5, in my_content_manager
self.entrance = True
NameError: name 'self' is not defined
这是为什么?我该如何解决这个错误?
谢谢。
错误 NameError: name 'self' is not defined
是不言自明的,没有双关语的意思。 self
只是 classes 方法中约定使用的名称。您没有在任何地方定义 self
,所以 Python 不知道该怎么做。此外,您已经定义了一个函数,而不是 class 中的方法,因此这离工作还很远。使用 class 来定义上下文管理器,如下所示:
class MyContextManager(object):
def __init__(self):
self.entrance = True
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
if exc_val:
self.entrance = False
# signal that the exception was handled and the program should continue
return True
with MyContextManager() as cm:
print (cm.entrance)
raise Exception()
print (cm.entrance)
编辑:如果按照评论中的要求,您只想打印一个值而不是将其存储在某处:
@contextmanager
def my_content_manager():
try:
yield
except Exception as ex:
print(False)
else:
print(True)
一般来说,使用 class 可能是更好的方法(正如其他答案所暗示的那样)。但是,我记得函数对象可以有属性。我遇到了 this 相关问题,这导致了以下技巧(这看起来确实是对该功能的滥用):
from contextlib import contextmanager
@contextmanager
def my_content_manager():
my_content_manager.entrance = True
try:
yield my_content_manager.entrance
finally:
my_content_manager.entrance = False
my_content_manager.entrance = False
with my_content_manager() as cm:
print(my_content_manager.entrance)
# Or, print(cm)
print(my_content_manager.entrance)
此技术可能存在缺陷。我只是出于好奇而发布它。