作用域,使用当前modu中的函数

2024-06-26 13:25:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我知道这肯定是一个小问题,但我已经尝试了许多不同的方法,并在quie中搜索了一些解决方案,但是如何在当前模块中创建和引用子函数呢?在

例如,我正在编写一个程序来解析一个文本文件,对于其中300个不同的名称,我想将其分配给一个类别。在

有300个这样的问题,我有一个列表来创建一个dict,所以形式lookup[key]=value(奖金问题;有没有比大规模dict更有效或更明智的方法呢?)。在

我想把所有这些都放在同一个模块中,但是在 文件的末尾,所以我不必向下滚动300行来查看代码,也就是说,如下面的例子所示。在

当我按如下方式运行它时,我得到错误“initlookups is not defined”。当我的结构是这样的,它是初始化,然后函数定义,然后函数使用,没问题。在

我确信肯定有一种明显的方法可以初始化函数和相关的dict,而不必保持代码内联,但是到目前为止已经尝试了很多次,但都没有成功。我可以把它放在一个外部模块中并导入它,但为了简单起见,我不希望这样做。在

在模块结构方面我应该做些什么?有没有比使用dict存储这个查找表更好的方法(它是300个唯一的文本键映射到大约10个类别?在

谢谢

布伦丹


import ..... (initialisation code,etc )

initLookups()          # **Should create the dict - How should this be referenced?**
print getlookup(KEY)   # **How should this be referenced?**


def initLookups():
    global lookup
    lookup={}
    lookup["A"]="AA"
    lookup["B"]="BB"
    (etc etc etc....)


def getlookup(value)
    if name in lookup.keys():
        getlookup=lookup[name]
    else:
        getlookup=""

    return getlookup

Tags: 模块方法函数代码valueetclookupthis
3条回答

如果lookup dict是不变的,最简单的方法就是将其作为模块范围变量。即:

lookup = {
    'A' : 'AA',
    'B' : 'BB',
    ...
}

如果您可能需要进行更改,然后重新初始化,您可以在初始化功能中执行此操作:

^{pr2}$

(或者,查找.更新({'A':'AA',…})更改dict,影响所有可以访问旧绑定的调用方。)

但是,如果您有一些标准格式的查找,那么从文件中加载并从中创建字典可能会更简单。在

你可以随意安排你的职能。关于排序的唯一规则是,被访问的变量必须在函数调用时存在-如果函数体中引用了尚不存在的变量,则没关系,只要没有实际尝试使用该函数。即:

def foo():
    print greeting, "World"  # Note that greeting is not yet defined when foo() is created

greeting = "Hello"

foo() # Prints "Hello World"

但是:

def foo():
    print greeting, "World"

foo()              # Gives an error - greeting not yet defined.
greeting = "Hello"

还有一件事需要注意:你的getlookup函数效率很低。使用“if name in lookup.keys()”实际上是从dict中获得一个键列表,然后在这个列表上迭代以找到该项。这就失去了dict提供的所有性能优势。相反,“if name in lookup”可以避免这种情况,或者更好地使用这样一个事实:如果键不在字典中,.get可以被赋予返回的默认值:

def getlookup(name)
    return lookup.get(name, "")

函数在被调用之前需要被定义。如果您想让需要在文件顶部执行的代码,只需定义一个main函数并从底部调用它:

import sys

def main(args):
    pass

# All your other function definitions here

if __name__ == '__main__':
    exit(main(sys.argv[1:]))

这样,您在main中引用的任何内容都将被解析,因此已经知道了。测试^{}的原因是,通过这种方式,main方法将只在脚本直接执行时运行,而不是在它被另一个文件导入时运行。在


旁注:一个有300个键的dict绝不是巨大的,但是您可能希望将填充dict的代码移动到一个单独的模块中,或者(也许更花哨)以JSON这样的格式存储键/值对,并在程序启动时加载它。在

这里有一个更像Python的方法。顺便说一句,没有太多的选择

函数必须先定义才能使用。句号。在

但是,您不必为了编译器的利益而严格地对所有函数进行排序。您只需将函数的执行放在最后。在

import # (initialisation code,etc )

def initLookups(): # Definitions must come before actual use
    lookup={}
    lookup["A"]="AA"
    lookup["B"]="BB"
    (etc etc etc....)
    return lookup

# Any functions initLookups uses, can be define here.
# As long as they're findable in the same module.

if __name__ == "__main__": # Use comes last
    lookup= initLookups() 
    print lookup.get("Key","")

注意,您不需要getlookup函数,它是dict的一个内置特性,名为get。在

另外,“初始化代码”也是可疑的。导入不应该“做”任何事情。它应该定义函数和类,但实际上不提供任何可执行代码。从长远来看,由导入处理的可执行代码可能会成为维护的噩梦。在

最值得注意的例外是默认情况下创建的模块级单例对象。即使这样,也要确保使模块工作的神秘对象在文档中被清楚地标识出来。在

相关问题 更多 >