简体   繁体   中英

Python function with more than one return (many returns problem)

during my studies on Python I read that it is not recommended a function to have more than one return. For example, this my function below:

def get_hero_names_from_database(id: int) -> dict:

    hero_names = {}

    try:
        connection = get_connection()
        cursor = connection.cursor()
        cursor.execute(get_names_query, (id,))
        names = cursor.fetchall()
        for name in names:
            hero_names = {
                "name": name[0],
                "localized_name": name[1]
            }
    except mysql.connector.Error as error:
        print("Failed to select hero names: {}".format(error))
    finally:
        cursor.close()
        close_connection(connection)

    # Check if select return is empty, that's it don't have hero with this ID.
    if hero_names:
        return hero_names
    else:
        print("There is no hero with this ID.")

The function takes names of a certain hero by ID from my Database and then transforms all this into a dictionary, however, when I pass an ID that does not exist, my dictionary will be empty since my Database will not return nothing. So far so good, I even create a condition to solve this problem:

# Check if select return is empty, that's it don't have hero with this ID.
if hero_names:
    return hero_names
else:
    print("There is no hero with this ID.")

NOTE:
The problem is that the above condition will return a None when my dictionary is empty and as I said at the beginning of the post it is not recommended for a Python function to have more than one return.

Knowing this I modified my condition to create an exception when my dictionary is empty:

# Check if select return is empty, that's it don't have hero with this ID.
if not hero_names:
    raise ValueError("There is no hero with this ID.")
else:
    return hero_names

Okay, now I have an exception that looks something like this when I have an empty dictionary:

Traceback (most recent call last):
  File "dota2learning/database.py", line 107, in <module>
    hero_names = get_hero_names_from_database(500)
  File "dota2learning/database.py", line 94, in get_hero_names_from_database
    raise ValueError("There is no hero with this ID.")
ValueError: There is no hero with this ID.

Now I have the following questions:

  • Is this output without much formatting normal?
    • I just wanted to see "There is no hero with this ID."

How do I test this output, because I created the assert below and it didn't work:

@pytest.mark.get_names
def test_get_hero_names_from_database_invalid_id():
    # Test the console return when pass invalid id, that's, no hero with this ID.
    result = get_hero_names_from_database(500)
    assert result == "There is no hero with this ID."

I passed an invalid ID just to test and I can't get this test to pass:

        # Check if select return is empty, that's it don't have hero with this ID.
        if not hero_names:
>           raise ValueError("There is no hero with this ID.")
E           ValueError: There is no hero with this ID.

dota2learning\database.py:94: ValueError
====================== short test summary info ======================
FAILED tests/database/test_database.py::test_get_hero_names_from_database_invalid_id - ValueError: There is no hero with this ID.
====================== 1 failed, 3 passed in 0.72s ==================

NOTE:
Finally, it is really recommended to avoid that a function returns a value that is not expected, for example None ?

Returning None when there is no value that can be returned is usually acceptable. If you call the function, and print the results, getting None when the ID has no match makes intuitive sense as there was no hero with that ID so there should be no information.

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