Method not found although exists in same py file

Question:

I am receiving the error as "NameError: name ‘GetASetting’ is not defined".

Log:

[INFO              ] Kivy v1.8.0
Purge log fired. Analysing...
Purge 60 log files
Purge finished !
[INFO              ] [Logger      ] Record log in C:UsersSudheer.kivylogskivy_14-07-18_10.txt
[INFO              ] [Factory     ] 157 symbols loaded
[DEBUG             ] [Cache       ] register <kv.lang> with limit=None, timeout=Nones
[DEBUG             ] [Cache       ] register <kv.image> with limit=None, timeout=60s
[DEBUG             ] [Cache       ] register <kv.atlas> with limit=None, timeout=Nones
[INFO              ] [Image       ] Providers: img_tex, img_dds, img_pygame, img_gif (img_pil ignored)
[DEBUG             ] [Cache       ] register <kv.texture> with limit=1000, timeout=60s
[DEBUG             ] [Cache       ] register <kv.shader> with limit=1000, timeout=3600s
 Traceback (most recent call last):
   File "C:Kivy180Python33librunpy.py", line 160, in _run_module_as_main
     "__main__", fname, loader, pkg_name)
   File "C:Kivy180Python33librunpy.py", line 73, in _run_code
     exec(code, run_globals)
   File "D:OS FilesworkspaceOrg__main__.py", line 7, in <module>
     from formcontrol import FormControl
   File "D:OS FilesworkspaceOrgformcontrol.py", line 8, in <module>
     from login.logincodes import LoginControl
   File "D:OS FilesworkspaceOrgloginlogincodes.py", line 7, in <module>
     from dbcodes.logins import LoginAccess
   File "D:OS FilesworkspaceOrgdbcodeslogins.py", line 2, in <module>
     from dbcodes.settings import GetASetting, SettingList
   File "D:OS FilesworkspaceOrgdbcodessettings.py", line 31, in <module>
     class SettingList(object):
   File "D:OS FilesworkspaceOrgdbcodessettings.py", line 36, in SettingList
     FirstRun_Get = GetASetting(FirstRun)
 NameError: name 'GetASetting' is not defined

Both the class and def are in same .py file.

Code:

def Initiation():
    from os import path
    print(Getcwd())
    folderpath=str(Getcwd()) 
    fpath = folderpath + "/orgapp.ini"
    dbpath = folderpath + "/orgapp.db"
    if path.exists(fpath)==False:
        
        #Writing Basic Values
        f = open(fpath,'w')
        setlist=SettingList()
        f.write(setlist.FirstRun+'|True' + 'n')
        f.write(setlist.IniPath+'|'+fpath + 'n')
        f.write(setlist.DBPath+'|'+dbpath + 'n')
        f.close()
        print('File Created')
        
        
        #Creating default database
        CreateDB(dbpath)
        
        return True
    else:
        print('File exists')
        return False

def GetASetting(settingtype):
        if settingtype=='': return None
        path = Getcwd() + '/orgapp.ini'
        f1=open(path,'r')
        for k in f1:
            k=k.replace('n','')
            c= (k.rsplit(sep='|', maxsplit=2))
            if settingtype.lower() == c[0].lower():
                f1.close()
                if c[1]=='': return None
                else: return c[1]
        f1.close()
        return None
       
class SettingList(object):
    FirstRun = 'FirstRun'
    IniPath='IniPath'
    DBPath='DBPath'
    
    FirstRun_Get = GetASetting(FirstRun)
    IniPath_Get = GetASetting(IniPath)
    DBPath_Get = GetASetting(DBPath)
       
    
    
def Getcwd():
    from os import getcwd
    p=''
    p=getcwd()
    p=p.replace('\', '/')
    return p
    
def CreateDB(dbpath):
    import sqlite3
    
    conn = sqlite3.Connection(dbpath, detect_types=sqlite3.PARSE_DECLTYPES|sqlite3.PARSE_COLNAMES)
    conn.execute('''
    create table login
    (loginid text, password text)    
    ''')
    
    #default user
    id='admin'
    pw='1234'
    conn.execute("insert into login (loginid, password) values (?,?)",(id,pw))
    
    
    conn.commit()
    conn.close()
     

I did a work around by placing the def in class, but, the above code should work, could you please enlighten me as to what error I did above, I checked the names and they are correct?

Asked By: surpavan

||

Answers:

GetASetting needs to exist before you can use it. With the way your code is structured, it does not. Define GetASetting before the class definition.

As Ignacio said, GetASetting needs to exist before you can use it. The exact reason is this: Class definitions as well as function signatures (where default values for arguments might contain executable code) are executed when the Python interpreter comes across them for the first time – hence, your function GetASetting needs to exist at this time already. (On the other hand, this also means that you could use if/else and other control flow statements in your class definition, too.)

Anyway, if you do not want this (and you usually don’t—due to unintuitive errors like the one you encountered), you should use a constructor for your class:

class SettingList(object):
    # All code in here is executed when the interpreter first
    # encounters the class definition
    def __init__(self): # The same applies for this line
        # This code only run when __init__() is actually called.
        self.FirstRun = 'FirstRun'
        self.IniPath='IniPath'
        self.DBPath='DBPath'

        # Now, the function definition below poses no problem.
        self.FirstRun_Get = GetASetting(FirstRun)
        self.IniPath_Get = GetASetting(IniPath)
        self.DBPath_Get = GetASetting(DBPath)

def GetASetting(settingtype):
    # […]
    return None


# usage example
settings = SettingList()
print(settings.FirstRun_Get) 

This is also a good idea in terms of testability – now every instance of SettingList is initialized upon creation such that, in theory, you could mock out dependencies like file access, i.e. the settings file on your disk.

Answered By: balu
Categories: questions Tags:
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.