方法未找到,尽管存在于同一py文件-python中

方法未找到,尽管存在于同一py文件-python中,python,Python,我是python新手,我的背景是VB。我收到的错误是“NameError:name'GetASetting'未定义” 日志: 我通过在类中放置def来解决问题,但是,上面的代码应该可以工作,您能告诉我上面发生了什么错误吗?我检查了名称,它们是正确的?GetASetting需要存在才能使用它。根据代码的结构方式,它不会。在类定义之前定义GetASetting。正如Ignacio所说,GetASetting需要存在才能使用它。确切的原因是:当Python解释器第一次遇到类定义和函数签名(参数的默认值

我是python新手,我的背景是VB。我收到的错误是“NameError:name'GetASetting'未定义”

日志:


我通过在类中放置def来解决问题,但是,上面的代码应该可以工作,您能告诉我上面发生了什么错误吗?我检查了名称,它们是正确的?

GetASetting
需要存在才能使用它。根据代码的结构方式,它不会。在类定义之前定义
GetASetting

正如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的每个实例都在创建时初始化,这样,理论上,您可以模拟文件访问等依赖项,即磁盘上的设置文件。

我用完整的代码编辑了这个问题,当我更改函数/方法的位置时,它会生效。我现在明白你说的了。然而,我如何才能纠正这一点,这是用python编写代码的正确方法吗?在VB中,这个流代码不会生效,请您详细解释一下。谢谢您的时间。@surpavan:请看下面我的答案。是的,但现在我需要对类进行初始化,可以不实例化吗?像单一方法等等?不,你不是在初始化这个类,而是初始化它的一个实例。除此之外,类的全部要点就是创建它的实例。如果您想要全局状态(我会避免,请参阅我关于可测试性的声明),请不要使用类(或),而是在模块范围中定义它。我知道这在Java这样的语言中是不可能的(我不知道VB),但在Python中是不可能的,这样做是有意义的当然,您可以定义一个来初始化类,但我强烈建议不要这样做,因为1。你会再次介绍全球国家,2。您仍然需要在正确的时间调用该方法,即在该类在其他任何地方使用之前。但现在您又依赖于执行顺序,完全模糊了代码的依赖关系。如何在应用程序级别定义全局变量,我使用的是kivy框架,这将有助于理解。在Python(因此,kivy)中,您可以简单地在模块范围内定义变量(=所有未缩进的变量),例如,您上面定义的所有功能都在模块范围内。然后,在模块代码的其余部分中,只需通过它们的名称就可以全局访问它们。此外,如果需要,还可以将此模块(包括其全局变量)导入到另一个模块中。请看一个相关的问题,但暂时忽略前两句话,而是看代码示例。
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()
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)