简体   繁体   English

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

[英]How can I access variables defined within if/elif statements at the end of the parent python function?

How can I reference variables defined within if/elif statements further on in the parent python (3.6) function? 如何在父python(3.6)函数中进一步引用if / elif语句中定义的变量?

for example, the below is a mock-up of my code - I am trying to 'print' or 'work with' variables defined in each 'if' and 'elif' block below, at the end of the function which contains the if/elif statements that the variables are defined within, however I get an unresolved reference error in pycharm and the following python error when I run the code: 例如,下面是我的代码的模型-我试图在包含if的函数结尾处“打印”或“使用”下面每个“ if”和“ elif”块中定义的变量/ elif语句中定义了变量,但是在运行代码时,我在pycharm中遇到未解决的引用错误,并且遇到以下python错误:

    UnboundLocalError: local variable 'a1_summary' referenced before assignment

I am relatively new to python and coding and don't understand where I am going wrong as I expect that as the variables are defined within the same function then they should be 'visible' to the print statement at the end of the function... 我对python和编码相对较新,并且不明白我要去哪里出了错,因为我期望变量是在同一函数中定义的,所以它们应该在函数末尾的print语句中“可见”。 。

Is this a case where global variables should be used? 这是应该使用全局变量的情况吗?

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

Any help or advice is much appreciated - thank you. 非常感谢您的任何帮助或建议-谢谢。

updated to the above 更新到上面

I was trying to keep the question simple but may have confused things as I am trying to use the if/elif statements within a function that process messages from a rabbitmq message queue - I need to process messages based on the number of commas in the respective message and assign the parts of the message to variables and then aggregate the parts from each message received and processed by the if/elif statements into one array so that I can then pass this to another function later on in my program. 我试图使问题保持​​简单,但可能会感到困惑,因为我试图在处理来自Rabbitmq消息队列的消息的函数中使用if / elif语句-我需要根据相应消息中的逗号数来处理消息message并将消息的各个部分分配给变量,然后将if / elif语句接收和处理的每条消息中的各个部分聚合到一个数组中,以便稍后将其传递给另一个函数。

I may be going wrong in thinking that each time the function receives incoming_data which matches either the if or elif statement - any previous or new data that matches the other condition will still be held as a variable within the function eg I am thinking that the function holds variables from both the if/elif blocks and only updates any new data processed by the corresponding logic statement... 我可能会以为错误的是,每次函数接收到与if或elif语句匹配的传入数据-匹配其他条件的任何先前数据或新数据仍将作为函数中的变量保存,例如,我认为该函数保留两个if / elif块中的变量,并且仅更新由相应逻辑语句处理的任何新数据...

Looking at your code, what I think you are trying to do can be done far more efficiently, and fix your error. 查看您的代码,我认为您要尝试执行的操作可以更有效地完成,并修复错误。 It looks like you are trying to split the input by commas then print each element. 看来您正在尝试用逗号分割输入,然后打印每个元素。 Instead of doing what you are doing now, you could put them in a list, and then print the list. 您可以将它们放在列表中,然后打印该列表,而不是现在执行操作。 I think this will do what you want 我想这会做你想要的

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

I am not really sure why you would do this, because it won't actually do anything except replace commas with spaces. 我不太确定为什么要这么做,因为除了用空格替换逗号之外,它实际上不会做任何事情。 If you want to return a tuple with the result, replace the print with 如果要返回结果的元组,请用

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

You can also make this into a lambda: 您也可以将其变成lambda:

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

or 要么

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

If you want to change the types of the variables based on the number, that can definitely be done. 如果您想根据数字更改变量的类型,那绝对可以做到。

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)

You can change the types as needed for the desired output. 您可以根据需要更改所需输出的类型。 This is pretty similar to what you did, except a little shorter, and defining the remaining data point as None. 这与您所做的非常相似,只是略微缩短一点,并将其余数据点定义为“无”。

The problem with your code is that a1_summary and b1_summary only get defined if your incoming data contains two commas, and in this case, a2_summary , b2_summary , and c2_summary will never get defined. 您的代码的问题在于,只有在传入数据包含两个逗号时才定义a1_summaryb1_summary ,在这种情况下,永远不会定义a2_summaryb2_summaryc2_summary

The reversed problem appears with 3 commas in the input - and both if there is less than 2 or more than 3 commas. 如果输入的逗号少于2个或大于3个,则在输入中出现3个逗号,反之亦然。

So, whatever your input is, some of your variables never get defined. 因此,无论您输入什么内容,都不会定义某些变量。

There is absolutely no problem of scope here. 这里绝对没有范围的问题。 If you want more information about scopes in Python 3, you can have a look at this answer . 如果您想了解有关Python 3中作用域的更多信息,请查看此答案

To solve your problem, you could give these variables default values at the beginning of the function. 为了解决您的问题,您可以在函数开始时为这些变量提供默认值。 This could be an empty string, for example 例如,这可以是一个空字符串

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

Then, whatever path your code takes, all variables will have been defined at some point. 然后,无论代码采用什么路径,所有变量都将在某个时刻定义。

If this code: 如果此代码:

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 )

causes this error: 导致此错误:

UnboundLocalError: local variable 'a1_summary' referenced before assignment

it can only be because a1_summary has not been assigned a value when you try to use it in the print statement. 只能是因为在尝试在print语句中使用a1_summarya1_summary分配值。

The only place you assign to a1_summary is in this block: 您分配给a1_summary的唯一位置是在此块中:

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

ergo this code hasn't been executed, which means that incoming_data.count(',') is not equal to 2 . 因此,此代码尚未执行,这意味着incoming_data.count(',')不等于2

This is also the reason why "the values don't seem to get updated" when you initialize a1_summary = "" etc. at the top of your function. 这也是在函数顶部初始化a1_summary = ""等时为什么“值似乎未更新”的原因。

If you want the function to remember previous values you should use a class instead, eg 如果要让函数记住以前的值,则应改用类,例如

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)

usage: 用法:

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

If you don't want to change your API, you can call the process method __call__ instead, and then use it as: 如果您不想更改您的API,则可以调用__call__ process方法,然后将其用作:

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

Thanks to all those who commented on my question, you have given me food for thought however I seem to have found a work around/solution to the problem as follows: 感谢所有对我的问题发表评论的人,您为我提供了思考的机会,但是我似乎找到了解决该问题的方法/解决方案,如下所示:

I created a config.py file and defined variables in it, eg 我创建了一个config.py文件并在其中定义了变量,例如

config.py

a1_summary = ""
b1_summary = ""

a2_summary = ""
b2_summary = ""
c2_summary = ""

Then in my 'main' python script file, I imported 'config' and referenced the variables it contains using the prefix 'config.' 然后,在我的“主要” python脚本文件中,导入了“ config”并使用前缀“ config”引用了其中包含的变量。 in my function - the updated code from my original example is shown below: 在我的函数中-来自原始示例的更新代码如下所示:

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

This now allows me to aggregate the values from each of the if/elif statements into the print statement at the bottom of the code. 现在,这使我可以将每个if / elif语句的值聚合到代码底部的print语句中。

I think using a class as suggested by thebjorn above may be the prefered way of doing this however as I am new to python/coding this is a little beyond my understanding at present and the solution above allows me to do what I need to for the moment. 我认为使用上述thebjorn建议的类可能是实现此目的的首选方式,但是由于我是python / code的新手,因此这超出了我的理解,并且上述解决方案允许我做我需要做的事情时刻。

I realise I need to learn more about classes and intend to do so as I think using these would be more elegant and remove the need for an external config.py file. 我意识到我需要了解有关类的更多信息,并打算这样做,因为我认为使用这些类会更优雅,并且不需要外部config.py文件。

I hope this may be useful to those who are currently in a similar position to myself. 我希望这对目前与我自己处于相似位置的人可能有用。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM