Search code examples
pythonfunctionnested-function

Access variable from a different function from another file


I have a file myfunctions.py in directory mypythonlib

from requests_html import HTMLSession
import requests

def champs_info(champname:str, tier_str:int):  
    url = f"https://auntm.ai/champions/{champname}/tier/{tier_str}"
    session = HTMLSession()
    r = session.get(url)
    r.html.render(sleep=1, keep_page=True, scrolldown=1)

    information = r.html.find("div.sc-hiSbYr.XqbgT")
    sig = r.html.find('div.sc-fbNXWD.iFMyOV')
    tier_access = information[0]
    tier = tier_access.text

I want to access the variable tier through another file- test_myfunctions.py but the thing is I also have to give parameters to the function champs_info so that it could access the url accordingly.

from mypythonlib import myfunctions
def test_champs_info():
    return myfunctions.champs_info("abomination",6).tier

But while running this code, I am getting the error-

./tests/test_myfunctions.py::test_champs_info Failed: [undefined]AttributeError: 'NoneType' object has no attribute 'tier'
def test_champs_info():
>       return myfunctions.champs_info("abomination",6).tier
E       AttributeError: 'NoneType' object has no attribute 'tier'

tests/test_myfunctions.py:3: AttributeError

Any Solution for this and why is this code not able to access the variable? I wrote myfunctions.champs_info("abomination",6).tier in hope for that it's gonna take the tier variable from the champs_info function while giving it the parameters required all from the myfunctions file :(


Solution

  • You can access the value of a variable in a function by 1) returning the value in the function, 2) use a global variable in the module, or 3) define a class.

    If only want to access a single variable local to a function then the function should return that value. A benefit of the class definition is that you may define as many variables as you need to access.

    1. Return value

    def champs_info(champname:str, tier_str:int):  
        ...
        tier = tier_access.text
        return tier
    

    2. global

    tier = None
    def champs_info(champname:str, tier_str:int):
        global tier
        ...
        tier = tier_access.text
    

    Global tier vairable is accessed.

    from mypythonlib import myfunctions
    
    def test_champs_info():
        myfunctions.champs_info("abomination", 6)
        return myfunctions.tier
    
    print(test_champs_info())
    

    3. class definition:

    class Champ:
        def __init__(self):
            self.tier = None
        def champs_info(self, champname:str, tier_str:int):  
            ...
            self.tier = tier_access.text
    

    test_functions.py can call champs_info() in this manner.

    from mypythonlib import myfunctions
    
    def test_champs_info():
        info = myfunctions.Champ()
        info.champs_info("abomination", 6)
        return info.tier
        
    print(test_champs_info())