Search code examples
pythonpython-importstring-operations

Why it is not possible to import a variable from a module by using string operators?


I have a list for variables of fruits in a python script:

VariableScript.py:

variableColorApple = "Red"
variableWeightApple = ["5", "6", "7"]
variablePriceApple = ["10", "15", "20"]
variableColorApple = "Orange"
variableWeightOrange =["8", "9", "10"]
variablePriceOrange =["10", "15", "20"]
#...

And I have another script, where I use user input (user's fruit choice), to run my analysis. I want to write only one script that I can runregardless of the user's fruit selection. So I could avoid if else statements and long scripts.

I thought I could use string operators to import variables, but with string operators python doesn't find the variable in VariableScript module. What else I can try?

I have also already tried operator.getattr(). But then I couldnt access the items in the gettattr().

Just to keep it simple and executable: Let's say the users' input is "Apple" and I just want to print the color of apple from VariablesScript.py. My code is:

from VariableScript import VariablesScript as Variables

userInput = "Apple"
print(Variables.variableColor + UserInput)`

Any idea how can I get the color or apple without actually writing apple?...


Solution

  • So what you're asking to do is technically possible, but it is definitely un-Pythonic and really not a stable design.

    Here's how to get your code to work:

    from VariableScript import VariablesScript as Variables
    
    userInput = "Apple"
    try:
        var = "variableColor" + userInput
        value = getattr(Variables, var)
    except AttributeError as e:
        print(f"The variable '{var}' is not defined.")
    else:
        print(value)
    

    A much better solution here would be to use a data structure such as a dictionary, which has string key lookup.

    #variables.py
    
    fruits = {
        "apple" : {
           "color": "Red",
           "weight": ["5", "6", "7"],
           "price" : ["10", "15", "20"]
           },
        "orange" : {
            "color": "Orange",
            "weight": ["8", "9", "10"],
            "price" : ["10", "15", "20"]
            }
    }
    
    
    #main.py
    
    from variables import fruits
    
    user_input = "Apple"
    
    fruit_data = fruits.get(user_input.lower())
    if fruit_data is None:
        fruit_folor = f"{user_input} was not found"
    else:
        fruit_color = fruit_data["color"]
    
    print(fruit_color)
    

    Edit: added safeguard for case where fruits.get(user_input.lower()) returns None and fixed my brackets.

    You may also want to look into DataClasses or NamedTuples as a data structure to use for each fruit. Also, if the weights and prices lists are meant to be in sync, then perhaps they should be a in a dictionary with weight as the key, and price as the value, or it should be a single list of tuples.