1

我知道这一定是一个微不足道的问题,但是我尝试了许多不同的方法,并且稍微搜索了一下解决方案,但是如何在当前模块中创建和引用子函数?

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

其中有 300 个,我有一个列表来创建一个 dict,所以形式为 lookup[key]=value (奖金问题;有比大量 dict 更有效或更明智的方法吗?)。

我想将所有这些保留在同一个模块中,但在文件末尾使用函数(dict初始化等),所以我不必向下滚动 300 行来查看代码,即布局如下面的例子。

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

我确信必须有一种明显的方法来初始化函数和相关的 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
4

4 回答 4

5

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

import sys

def main(args):
    pass

# All your other function definitions here

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

这样,您引用的任何内容都main将被解析,因此已经为人所知。测试的原因__name__是这样的main方法只会在脚本直接执行时运行,而不是在被另一个文件导入时运行。


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

于 2009-05-29T09:04:40.753 回答
1

这是一个更pythonic的方法来做到这一点。顺便说一句,没有太多选择。

必须先定义函数,然后才能使用它。时期。

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

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

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

最值得注意的例外是默认创建的模块级 Singleton 对象。即便如此,请确保使模块工作的神秘对象在文档中明确标识。

于 2009-05-29T10:34:29.417 回答
0

如果您的查找字典不变,最简单的方法是将其设为模块范围变量。IE:

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

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

def initLookups():
    global lookup
    lookup = {
        'A' : 'AA',
        'B' : 'BB',
        ...
    }

(或者,lookup.update({'A':'AA', ...}) 就地更改字典,影响所有可以访问旧绑定的调用者。)

但是,如果您以某种标准格式获得这些查找,则只需从文件中加载它并从中创建字典可能会更简单。

您可以根据需要安排功能。关于排序的唯一规则是访问的变量必须在调用函数时存在- 如果函数引用了主体中尚不存在的变量,这很好,只要没有实际尝试使用该函数。IE:

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 提供的所有性能优势。相反,“ if name in lookup”会避免这种情况,甚至更好的是,.get如果键不在字典中,则可以使用默认返回的事实:

def getlookup(name)
    return lookup.get(name, "")
于 2009-05-29T10:32:39.373 回答
0

我认为将名称保存在平面文本文件中并在运行时加载它们将是一个不错的选择。我尝试将我的数据尽可能保持在最低级别的复杂性,从纯文本开始,一直到 RDMS(我从The Pragmatic Programmer中提出了这个想法)。

字典在 python 中非常有效。它本质上是整个语言的基础。300 个项目完全在理智的 dict 使用范围内。

名称.txt:

A = AAA
B = BBB
C = CCC

获取名称.py:

import sys

FILENAME = "names.txt"

def main(key):
    pairs = (line.split("=") for line in open(FILENAME))
    names = dict((x.strip(), y.strip()) for x,y in pairs)
    return names.get(key, "Not found")

if __name__ == "__main__":
    print main(sys.argv[-1])

如果出于某种原因你真的想把它全部放在一个模块中,你可以在模块的顶部粘贴一个字符串。我认为一大段文本比一大堆 dict 初始化代码更容易分散注意力(以后更容易编辑):

import sys

LINES = """
A = AAA
B = BBB
C = CCC
D = DDD
E = EEE""".strip().splitlines()

PAIRS = (line.split("=") for line in LINES)
NAMES = dict((x.strip(), y.strip()) for x,y in PAIRS)

def main(key):
    return NAMES.get(key, "Not found")

if __name__ == "__main__":
    print main(sys.argv[-1])
于 2009-05-31T23:43:14.163 回答