在python3中引用全局变量时处理'NameError',而不引发'SyntaxError' 处理名称错误会引发语法错误:
因此,我正在制作一个decorator函数,它将生成器函数与字典相关联,目的是使在python3中引用全局变量时处理'NameError',而不引发'SyntaxError' 处理名称错误会引发语法错误:,python,python-3.x,exception,exception-handling,decorator,Python,Python 3.x,Exception,Exception Handling,Decorator,因此,我正在制作一个decorator函数,它将生成器函数与字典相关联,目的是使send()函数使用起来不那么麻烦 默认行为是使用全局名称空间中定义的名为global\u registry\u dict的字典 如果global\u registry\u dict不存在,并且没有显式传入替代字典,则python会引发namererror 当我试图通过在全局名称空间中创建变量来处理错误时,我得到一个SyntaxError告诉我在赋值之前引用了该变量。这是有道理的…但是…就像…这就是我想要解决的问题
send()
函数使用起来不那么麻烦
默认行为是使用全局名称空间中定义的名为global\u registry\u dict
的字典
如果global\u registry\u dict
不存在,并且没有显式传入替代字典,则python会引发namererror
当我试图通过在全局名称空间中创建变量来处理错误时,我得到一个SyntaxError
告诉我在赋值之前引用了该变量。这是有道理的…但是…就像…这就是我想要解决的问题
任何帮助都将不胜感激
装饰师的来源:
整个模块的来源:
#全局注册表_dict={}
def使成为无状态参与者(func):
"""
说明:
===========
此DECORATOR函数简化并集中了生成器上“send()”的使用。
它通过将修饰函数关联到字典来实现这一点:
-默认情况下,将使用名为“global\u registry\u dict”的全局变量。
-默认情况下,如果global-NAMESPACE不存在,`global\u registry\u dict={}`将在该名称空间中创建。
重要提示:
==============
使用'registry_dict`kwarg手动将生成器func分配给备用字典:
`foo\u修饰的func(注册表dict=foo\u替代字典)`
要求:
============
您可以将“@make\u stateless\u actor”应用于以下任何生成器函数:
-在“=”符号的右侧包含一个“yield”表达式。
-包括`**kwargs`作为函数参数。
"""
def包装(注册表_dict=None,*args,**kwargs):
尝试:
如果registry_dict为None:#在else
子句中使用名称global_registry_dict
。如果它是全局的,您必须在使用它之前声明它,就像错误消息所说的那样。通常,名称在函数的开头被声明为全局的。我可以在开头添加一个检查,但我想我应该澄清一下:在使用之后,除了发现它还不存在之外,是否没有其他方法实例化全局变量?是的。做你正在做的,除了将全局
声明移到第一次使用名称上面,就像我刚才说的。Lol。是的。谢谢
def make_stateless_actor(func):
def wrapper(registry_dict=None, *args, **kwargs):
try:
if registry_dict is None:
internal_registry_dict = global_registry_dict
elif isinstance(registry_dict, dict) or issubclass(registry_dict, dict):
internal_registry_dict = registry_dict
else:
internal_registry_dict = global_registry_dict
except NameError: # <<== CATCHES IF `global_registry_dict` IS REF'D BUT NOT DEFINED.
global global_registry_dict # <<== SYNTAX ERROR HAPPENS HERE
global_registry_dict = {}
internal_registry_dict = global_registry_dict
gen = func(*args, **kwargs)
next(gen)
internal_registry_dict[func.__name__] = gen
return wrapper
File "C:/yall/dont/need/to/know/this/generator_pipeline_utils.py", line 74
global global_registry_dict
^
SyntaxError: name 'global_registry_dict' is used prior to global declaration
# global_registry_dict = {}
def make_stateless_actor(func):
"""
DESCRIPTION:
===========
This DECORATOR FUNCTION simplifies & centralizes the use of `send()` on generators.
It does this by ASSOCIATING the decorated function to a dictionary:
- by default, a global variable named `global_registry_dict` will be used.
- by default, `global_registry_dict = {}` will be created in the GLOBAL-NAMESPACE if it does not exist.
IMPORTANT NOTE:
==============
Use the `registry_dict` kwarg to manually assign your generator-func to an alternate dictionary:
`foo_decorated_func(registry_dict=foo_alternative_dictionary)`
REQUIREMENTS:
============
You can apply `@make_stateless_actor` to any GENERATOR FUNCTION which:
- INCLUDES A `yield` expression to the RIGHT of an `=` sign.
- INCLUDES `**kwargs` as a function argument.
"""
def wrapper(registry_dict=None, *args, **kwargs):
try:
if registry_dict is None: # <<-- necessary to prevent the next elif from throwing an exception.
internal_registry_dict = global_registry_dict
elif isinstance(registry_dict, dict) or issubclass(registry_dict, dict):
internal_registry_dict = registry_dict
else:
internal_registry_dict = global_registry_dict
except NameError:
print('WARNING: global_registry_dict IS NOT DEFINED AND YOU DID NOT EXPLICITLY PASS registry_dict TO THE DECORATED FUNCTION.\n\
`global_registry_dict = {}` has been instantiated in the global-namespace.\n')
global global_registry_dict
global_registry_dict = {}
internal_registry_dict = global_registry_dict
gen = func(*args, **kwargs)
next(gen)
internal_registry_dict[func.__name__] = gen
return wrapper
@make_stateless_actor
def printer(*args, **kwargs):
while True:
item = yield
print("Got: ", item)
def send(name, msg, registry_dict=None):
if registry_dict is None:
global_registry_dict[name].send(msg)
else:
registry_dict[name].send(msg)
if __name__ == "__main__":
printer(registry_dict=None) #<<==BEGIN THE CRAZY.
# send('printer', 'HEY WHAT IS UP?')
# send('printer', 666)
# send('printer', [1, 'a', [], True])