python3 - 修饰函数:赋值前引用的变量
python3 - decorator function: Variable referenced before assignment
我正在开发 gRPC 微服务。
因为每个方法都必须首先从 request
参数加载一个 JSON 字符串——然后最后再次转储它,我想在 [= 的方法上使用装饰器47=],所以除了return
之外的方法本身只包含下面的... more stuff to do ...
:
class VPPSetupService(SetupService_pb2_grpc.VPPSetupServiceServicer):
...
def method(self, request, context):
request = json.loads(request.context)
request = request["request"]
header = request["headers"]
... more stuff to do ...
response = json.dumps(response)
return SetupService_pb2.JsonContextResponse(context=response)
所以我写了一个装饰器函数。
但是,我找不到 这个错误:
的解决方案
request = json.loads(request.context)
UnboundLocalError: local variable 'request' referenced before assignment
错误是这样产生的:(只是举个例子,实际情况要复杂一些)
from functools import wraps
def json_and_error(func):
@wraps(func)
def args_wrapper(*args, **kwargs): # Problem: This
request = json.loads(request.context) <<# variable is referenced
request = request["request"] # before assignment
header = request["headers"]
func(*args, **kwargs)
return func(*args, **kwargs)
return args_wrapper
class VPPSetupService(SetupService_pb2_grpc.VPPSetupServiceServicer):
...
@json_and_error
def method(self, request, context):
... more stuff to do ...
return SetupService_pb2.JsonContextResponse(context=response)
我尝试改用 request = json.loads(args[1].context)
。但后来我得到这个错误:
if request["source_machine"] and request["dest_machine"]: TypeError:
'JsonContextRequest' object is not subscriptable
作为 request
参数给出的输入是类型为 <class 'SetupService_pb2.JsonContextRequest'>
的对象。请求中的 JSON 字符串可通过 request.context
属性访问。
我认为问题与装饰函数的调用方式有关。我想如果它是在 class 方法运行时调用的,变量 request 应该已经被分配了请求对象。
但也许我完全错了。那么你会如何解决这个问题?
您的代码中有一些错误:
def args_wrapper(*args, **kwargs):
request = json.loads(request.context)
您正在使用 request.context
,而 request
变量未定义(只有在 json.loads(request.context)
执行后才会定义)。您尝试使用 request = json.loads(args[1].context)
修复它,但在包装函数中得到了 JsonContextRequest object is not subscriptable
。仔细看看这条线:
return func(*args, **kwargs)
你的装饰器 returns 包装函数使用相同的参数调用,所以这个代码结果没有被使用,你没有将请求和 header 传递给包装函数:
request = json.loads(request.context)
request = request["request"]
header = request["headers"]
另外你不应该调用包装函数:
func(*args, **kwargs)
我猜你想做这样的事情:
def json_and_error(func):
def args_wrapper(this, request):
context = request.context
request = json.loads(context)
request = request["request"]
return func(this, request, context)
return args_wrapper
我正在开发 gRPC 微服务。
因为每个方法都必须首先从 request
参数加载一个 JSON 字符串——然后最后再次转储它,我想在 [= 的方法上使用装饰器47=],所以除了return
之外的方法本身只包含下面的... more stuff to do ...
:
class VPPSetupService(SetupService_pb2_grpc.VPPSetupServiceServicer):
...
def method(self, request, context):
request = json.loads(request.context)
request = request["request"]
header = request["headers"]
... more stuff to do ...
response = json.dumps(response)
return SetupService_pb2.JsonContextResponse(context=response)
所以我写了一个装饰器函数。 但是,我找不到 这个错误:
的解决方案request = json.loads(request.context)
UnboundLocalError: local variable 'request' referenced before assignment
错误是这样产生的:(只是举个例子,实际情况要复杂一些)
from functools import wraps
def json_and_error(func):
@wraps(func)
def args_wrapper(*args, **kwargs): # Problem: This
request = json.loads(request.context) <<# variable is referenced
request = request["request"] # before assignment
header = request["headers"]
func(*args, **kwargs)
return func(*args, **kwargs)
return args_wrapper
class VPPSetupService(SetupService_pb2_grpc.VPPSetupServiceServicer):
...
@json_and_error
def method(self, request, context):
... more stuff to do ...
return SetupService_pb2.JsonContextResponse(context=response)
我尝试改用 request = json.loads(args[1].context)
。但后来我得到这个错误:
if request["source_machine"] and request["dest_machine"]: TypeError:
'JsonContextRequest' object is not subscriptable
作为 request
参数给出的输入是类型为 <class 'SetupService_pb2.JsonContextRequest'>
的对象。请求中的 JSON 字符串可通过 request.context
属性访问。
我认为问题与装饰函数的调用方式有关。我想如果它是在 class 方法运行时调用的,变量 request 应该已经被分配了请求对象。
但也许我完全错了。那么你会如何解决这个问题?
您的代码中有一些错误:
def args_wrapper(*args, **kwargs):
request = json.loads(request.context)
您正在使用 request.context
,而 request
变量未定义(只有在 json.loads(request.context)
执行后才会定义)。您尝试使用 request = json.loads(args[1].context)
修复它,但在包装函数中得到了 JsonContextRequest object is not subscriptable
。仔细看看这条线:
return func(*args, **kwargs)
你的装饰器 returns 包装函数使用相同的参数调用,所以这个代码结果没有被使用,你没有将请求和 header 传递给包装函数:
request = json.loads(request.context)
request = request["request"]
header = request["headers"]
另外你不应该调用包装函数:
func(*args, **kwargs)
我猜你想做这样的事情:
def json_and_error(func):
def args_wrapper(this, request):
context = request.context
request = json.loads(context)
request = request["request"]
return func(this, request, context)
return args_wrapper