方法未找到,但在同一py文件中存在

-1 投票
2 回答
2683 浏览
提问于 2025-04-18 13:48

我遇到了一个错误,提示“NameError: name 'GetASetting' is not defined”。

日志:

[INFO              ] Kivy v1.8.0
Purge log fired. Analysing...
Purge 60 log files
Purge finished !
[INFO              ] [Logger      ] Record log in C:\Users\Sudheer\.kivy\logs\kivy_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:\Kivy180\Python33\lib\runpy.py", line 160, in _run_module_as_main
     "__main__", fname, loader, pkg_name)
   File "C:\Kivy180\Python33\lib\runpy.py", line 73, in _run_code
     exec(code, run_globals)
   File "D:\OS Files\workspace\Org\__main__.py", line 7, in <module>
     from formcontrol import FormControl
   File "D:\OS Files\workspace\Org\formcontrol.py", line 8, in <module>
     from login.logincodes import LoginControl
   File "D:\OS Files\workspace\Org\login\logincodes.py", line 7, in <module>
     from dbcodes.logins import LoginAccess
   File "D:\OS Files\workspace\Org\dbcodes\logins.py", line 2, in <module>
     from dbcodes.settings import GetASetting, SettingList
   File "D:\OS Files\workspace\Org\dbcodes\settings.py", line 31, in <module>
     class SettingList(object):
   File "D:\OS Files\workspace\Org\dbcodes\settings.py", line 36, in SettingList
     FirstRun_Get = GetASetting(FirstRun)
 NameError: name 'GetASetting' is not defined

这个类和函数都在同一个.py文件里。

代码:

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()
     

我通过把这个函数放进类里解决了问题,但我觉得上面的代码应该也能正常工作。你能帮我看看我上面哪里出错了吗?我检查过名字,都是对的。

2 个回答

2

在你使用GetASetting之前,它必须先被定义出来。根据你现在的代码结构,它并没有被定义。你需要在类的定义之前先写出GetASetting

0

正如Ignacio所说,GetASetting 必须在你使用它之前就已经存在。具体原因是这样的:当Python解释器第一次遇到类定义和函数签名时,它会执行这些代码(因为默认参数的值可能包含可执行的代码),所以你的函数GetASetting 必须在这个时候就已经存在了。(另一方面,这也意味着你可以在类定义中使用if/else等控制流语句。)

不过,如果你不想这样(通常你也不想,因为会出现一些不太直观的错误,比如你遇到的那种),那么你应该为你的类使用构造函数:

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) 

从可测试性的角度来看,这也是个好主意——现在每个SettingList的实例在创建时都会被初始化,这样理论上你可以模拟一些依赖,比如文件访问,也就是你硬盘上的设置文件。

撰写回答