简体   繁体   中英

NameError while calling a function (looking for a cleaner way to write the code)

I have a file which contains extracted data in the form of python variables. I expect this data to always come in form of 2 variables(check, output_check). The problem is that there are cases in which data is either incomplete(just the check variable) or data could not be extracted(meaning no variable at all).The contents of the file will always be different based on the data it extracted. Here is an example of a file:

check_1 = "Warning, the check has failed"
output_check_1 = "Here is a more detailed result."
check_2 = "Warning, the check has failed"
#There is no output_check_2 variable
#There is no check_3 at all

Next up, a function will generate a report based on the data from the file:

def create_report(check, output_check):
 if check.startswith("Warning"):
   print(check)
   if output_check:
    print(output_check)
   else:
    print("Sorry, couldn't get a more detailed result")
 else:
   print("Check was successful.")

#Let's call the function
create_report(check_1, output_check_1) #Works
create_report(check_2, output_check_2) #-> NameError because in this case output_check_2 does not exist 
create_report(check_3, output_check_3) #-> NameError because none of the arguments exist

As a fix, I came up with the following:

try:
 create_report(check_2, output_check_2)
except NameError:
 output_check_2 = ""
 try:
  create_report(check_2, output_check_2)
 except NameError:
  print("Error - data could not be extracted from the server!")

This way, if argument 2 (output_check_2) is missing I will just receive the result of the check without detailed data and if both arguments are missing(check_3, output_check_3) I am going to receive an error stating that the data could not be extracted at all.

The thing is that I find my "fix" rather barbaric and I am looking for a cleaner way in which to have the same result given that the function will be called many times during execution.

Edit: The variables come from an extraced_data.py file which I import at the start of the script. Unfortunately, I have no access to the script which generated the variables in the fist place thus encountering this issue.

You could also pass (*argv) instead of (check, output_check). This allows you to pass any number of arguments into your function.

def create_report(*argv):
    if argv[0].startswith("Warning"):   # argv[0] is your 'check' variable
        print(argv[0])
        if len(argv) > 1:    
            print(argv[1])   # argv[1] is your output_check variable
        else:
            print("No more info.")
    else:
            print("Check successful")

Assuming there's no way to fix how the data is stored * , you could use getattr to deal with the missing data. I'm assuming that you're doing something like this to import:

from dataScript import *

Change that to this:

import dataScript

Then you can do:

check1 = getattr(dataScript, "check1", None)  # Will default to None if it doesn't exist
if check1 is not None:
    create_report(check_1, getattr(dataScript, "output_check1", None))

Or, if you're on Python 3.8+ and the check variable will never be an empty string:

if check1 := getattr(dataScript, "check1", None):
    create_report(check_1, getattr(dataScript, "output_check1", None))

If you have an arbitrary number of these variables, you may need to use a loop. Something like:

for i in range(MAX_VARS):
    n = i + 1
    if check := getattr(dataScript, f"check{n}", None):
        create_report(check_, getattr(dataScript, f"output_check{n}", None))

Where MAX_VARS is the highest variable that you're expecting.


* The input format here is really the issue though. Using a Python script as a database that only sometimes has the correct data seems like the real problem. My solution above is just a workaround.

All you have to do is to change create_report function.

def create_report(check, output_check):
 if not check:
   print("Error - data could not be extracted from the server!")
   return
 if not output_check:
    output_check = ""

 if check.startswith("Warning"):
   print(check)
   if output_check:
    print(output_check)
   else:
    print("Sorry, couldn't get a more detailed result")
 else:
   print("Check was successful.")

Now you can just call the function without try-except block.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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