如何访问父 Python 函数末尾的 if/elif 语句中定义的变量



如何在父 Python (3.6) 函数中进一步引用在 if/elif 语句中定义的变量?

下面是我的代码模型 - 我正在尝试"打印"或"使用"下面每个"if"和"elif"块中定义的变量,在包含定义变量的 if/elif 语句的函数末尾,但是我在 Pycharm 中遇到未解决的引用错误,并在运行代码时出现以下 Python 错误:

UnboundLocalError: local variable 'a1_summary' referenced before assignment

我对 Python 和编码相对较新,不明白我哪里出错了,因为我希望由于变量是在同一函数中定义的,那么它们应该对函数末尾的 print 语句"可见"......

这是应该使用全局变量的情况吗?

def Process_Data(incoming_data):
if incoming_data.count(',') == 2:
data_summary = incoming_data.split(',')
a1_summary, b1_summary = data_summary[0], data_summary[1]
elif incoming_body.count(',') == 3:
data_summary = incoming_data.split(',')
a2_summary, b2_summary, c2_summary = data_summary[0], data_summary[1], data_summary[2]
print(a1_summary, b1_summary, a2_summary, b2_summary, c2_summary )
else:
pass

更新

我试图使问题保持简单,但可能会混淆事情,因为我试图在处理来自 RabbitMQ 消息队列的消息的函数中使用 if/elif 语句 - 我需要根据相应消息中的逗号数量处理消息并将消息的各个部分分配给变量,然后将 if/elif 语句接收和处理的每条消息中的部分聚合到一个数组,以便我可以稍后在程序中将其传递给另一个函数。

我可能错误地认为,每次函数收到与 if 或 elif 语句匹配的incoming_data - 任何与其他条件匹配的先前或新数据仍将作为函数中的变量保存,例如我认为该函数包含来自 if/elif 块的变量,并且只更新由相应逻辑语句处理的任何新数据......

代码的问题在于,只有当传入的数据包含两个逗号时,才会定义a1_summaryb1_summary,在这种情况下,a2_summaryb2_summaryc2_summary永远不会被定义。

反向问题出现在输入中 3 个逗号 - 如果逗号少于 2 个或超过 3 个逗号,则两者都出现。

因此,无论您的输入是什么,您的某些变量都不会被定义。

这里绝对没有范围问题。如果你想了解更多关于 Python 3 中作用域的信息,你可以看看这个答案。

为了解决您的问题,您可以在函数的开头为这些变量提供默认值。例如,这可能是一个空字符串

a1_summary = b1_summary = a2_summary = b2_summary = c2_summary = ''

然后,无论您的代码采用什么路径,所有变量都将在某个时候定义。

看看你的代码,我认为你正在尝试做的事情可以更有效地完成,并修复你的错误。看起来您正在尝试用逗号拆分输入,然后打印每个元素。与其执行现在正在执行的操作,不如将它们放在列表中,然后打印列表。我认为这会做你想要的

def Process_Data(incoming_data):
print(*incoming_data.split(","))

我不太确定你为什么要这样做,因为它实际上不会做任何事情,除了用空格替换逗号。如果要返回包含结果的元组,请将打印替换为

return(tuple(incoming_data.split(",")))

你也可以把它做成一个lambda:

Process_data = lambda incoming_data: print(*incoming_data.split(","))

Process_data = lambda incoming_data: return(tuple(incoming_data.split(",")))

如果你想根据数字改变变量的类型,那绝对可以做到。

def Process_Data(incoming_data):
data_input = incoming_data.split(",")
if len(data_input) == 3:
dataA, dataB, dataC = int(data_input[0]), str(data_input[1]), int(data_table[2])
elif len(data_input) == 2:
dataA, dataB, dataC = str(data_input[0]), int(data_input[1]), None
return(dataA, dataB, dataC)

您可以根据需要更改所需输出的类型。这与您所做的非常相似,只是更短一点,并将剩余数据点定义为 None。

如果此代码:

def Process_Data(incoming_data):
if incoming_data.count(',') == 2:
data_summary = incoming_data.split(',')
a1_summary, b1_summary = data_summary[0], data_summary[1]
elif incoming_body.count(',') == 3:
data_summary = incoming_data.split(',')
a2_summary, b2_summary, c2_summary = data_summary[0], data_summary[1], data_summary[2]
print(a1_summary, b1_summary, a2_summary, b2_summary, c2_summary )

导致此错误:

UnboundLocalError: local variable 'a1_summary' referenced before assignment

这只能是因为当您尝试在print语句中使用它时a1_summary尚未为其赋值。

分配给a1_summary的唯一位置是在此块中:

if incoming_data.count(',') == 2:
data_summary = incoming_data.split(',')
a1_summary, b1_summary = data_summary[0], data_summary[1]
^^^^^^^^^^

因此,此代码尚未执行,这意味着incoming_data.count(',')不等于2

这也是为什么当您在函数顶部初始化a1_summary = ""等时"值似乎没有更新"的原因。

如果您希望函数记住以前的值,则应改用类,例如

class DataProcessor(object):
def __init__(self):
self.a1 = self.a2 = self.b1 = self.b2 = self.c2 = ""
def process(incoming_data):
comma_count = incoming_data.count(',')
if comma_count == 2:
self.a1, self.b1 = data_summary[0], data_summary[1]
elif comma_count == 3:
self.a2, self.b2, self.c2 = ... you get the point...
else:
pass  # or log if it's an error condition
self.print_summary()
def print_summary(self):
print(self.a1, self.b1, self.a2, self.b2, self.c2)

用法:

dp = DataProcessor()
...
dp.process(data)

如果不想更改 API,可以改为调用process方法__call__,然后将其用作:

Process_Data = DataProcessor()  # keep original function name
...
Process_Data(data)  # calls DataProcessor.__call_

感谢所有对我的问题发表评论的人,您给了我思考的食物,但是我似乎找到了解决问题的方法/解决方案,如下所示:

我创建了一个 config.py 文件并在其中定义了变量,例如

config.py
a1_summary = ""
b1_summary = ""
a2_summary = ""
b2_summary = ""
c2_summary = ""

然后在我的"主"python脚本文件中,我导入了"config",并在我的函数中使用前缀"config."引用了它包含的变量 - 我的原始示例中的更新代码如下所示:

import config
...
def Process_Data(incoming_data):
if incoming_data.count(',') == 2:
data_summary = incoming_data.split(',')
config.a1_summary, config.b1_summary = config.data_summary[0], config.data_summary[1]
elif incoming_body.count(',') == 3:
data_summary = incoming_data.split(',')
config.a2_summary, config.b2_summary, config.c2_summary = config.data_summary[0], config.data_summary[1], config.data_summary[2]
print(config.a1_summary, config.b1_summary, config.a2_summary, config.b2_summary, config.c2_summary )
else:
pass

现在,这允许我将每个 if/elif 语句中的值聚合到代码底部的 print 语句中。

我认为使用上面thebjorn建议的类可能是这样做的首选方法,但是由于我是python/编码的新手,这目前有点超出我的理解范围,上面的解决方案允许我做我需要做的事情目前。

我意识到我需要更多地了解类并打算这样做,因为我认为使用这些类会更优雅,并且不需要外部 config.py 文件。

我希望这对目前与我处境相似的人有用。

由于作用域,您必须在 if/elif 块外部定义它们,然后在内部重新定义它们。

相关内容

  • 没有找到相关文章

最新更新