【问题标题】:Passing in Global Variables in Python在 Python 中传递全局变量
【发布时间】:2013-07-16 13:32:02
【问题描述】:

我是一位经验丰富的 Java 程序员,正在用 Python 重新实现一些代码,因为我只是在学习这门语言。我遇到的问题是,当我传入全局变量时,一个方法没有返回任何内容,但在传入文字时返​​回预期的代码。代码返回传入的指定长度的单词列表,从传递的字符串开始例如:

print getNGramBeginsWords("ha", 5)

返回

['HAAFS', 'HAARS', 'HABIT', 'HABUS', 'HACEK', 'HACKS', 'HADAL', 'HADED', 'HADES',
 'HADJI', 'HADST', 'HAEMS', 'HAETS', 'HAFIZ', 'HAFTS', 'HAHAS', 'HAIKA', 'HAIKS',
 'HAIKU', 'HAILS', 'HAINT', 'HAIRS', 'HAIRY', 'HAJES', 'HAJIS', 'HAJJI', 'HAKES', 
 'HAKIM', 'HAKUS', 'HALAL', 'HALED', 'HALER', 'HALES', 'HALID', 'HALLO', 'HALLS',
 'HALMA','HALMS', 'HALON', 'HALOS', 'HALTS', 'HALVA', 'HALVE', 'HAMAL', 'HAMES',
 'HAMMY', 'HAMZA', 'HANCE', 'HANDS', 'HANDY', 'HANGS', 'HANKS', 'HANKY', 'HANSA', 
 'HANSE', 'HANTS', 'HAOLE', 'HAPAX', 'HAPLY', 'HAPPY', 'HARDS', 'HARDY', 'HARED',
 'HAREM', 'HARES', 'HARKS', 'HARLS', 'HARMS', 'HARPS', 'HARPY', 'HARRY', 'HARSH', 
 'HARTS', 'HASPS', 'HASTE', 'HASTY', 'HATCH', 'HATED', 'HATER', 'HATES', 'HAUGH', 
 'HAULM', 'HAULS', 'HAUNT', 'HAUTE', 'HAVEN', 'HAVER', 'HAVES', 'HAVOC', 'HAWED', 
 'HAWKS', 'HAWSE', 'HAYED', 'HAYER', 'HAYEY', 'HAZAN', 'HAZED', 'HAZEL', 'HAZER', 
 'HAZES']

应该如此。不过,

print inputString
print numLetters
print getNGramBeginsWords(inputString, numLetters)

返回

ha
5
[]

inputString 和 numLetters 是全局变量,我已经看到它们被称为“危险”,尽管我不知道为什么,并认为它们可能是造成这种奇怪现象的原因?即使是用作参数的全局变量的本地副本也无济于事。也许我需要在方法的参数中使用“全局”关键字,尽管从我的研究看来,除非您更改全局变量,否则您不需要“全局”关键字?任何建议或帮助将不胜感激。万一这是方法的问题,这里是:

def getNGramBeginsWords(nGram, length):
    dict = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in dict:
        if(len(line)>0):
            if(len(nGram)>len(line.strip()) | len(line.strip())!= length):
                continue
            s = line.strip()[:len(nGram)]
            if(s == nGram and len(line.strip()) == length):
                words.append(line.strip())
    return words

【问题讨论】:

  • 如果你:print type(numLetters) 在调用getNGramBeginsWords 之前,你会得到<type 'int'> 还是<type 'str'>?我怀疑你得到后者,所以对于每一行,你将行的长度与字符串"5" 进行比较。 (旁注:dict 是 Python 中类型的名称。您可以将它们重新用作局部变量,当您尝试通过调用 dict 来创建字典时,这只会让人感到惊讶。也许使用 @987654333 @ 代替变量名 :-) )
  • 你确定它是你想要的if(len(nGram)>len(line.strip()) | len(line.strip())!= length) 中的|。因为,在 Python 中,| 是按位或,or 是布尔或。
  • 另外,不要忘记关闭dict 文件。尝试使用with open(..., 'r') as dict: 语句。

标签: python function types parameters global-variables


【解决方案1】:

tl;dr:全局变量与此无关;几乎可以肯定,您传递的是字符串而不是 int 作为长度参数。您的代码有很多冗余。

您的代码有许多明显的问题,包括风格和实质:

def getNGramBeginsWords(nGram, length):
    # dict is the name of a builtin function, which you are confusingly overwriting
    # dict = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in wlist:
        # an empty string evaluates to False in a binary context; also no need for those brackets
        stripline = line.strip().upper() # you keep doing this; I added the upper here.
        # you don't need this if, because you immediately test length
        #if stripline: #I know I changed this, but you only refer to the stripped version below 
        # pipe | is bitwise OR. I bet you don't want that
        if len(nGram)>len(stripline) or len(stripline)!= length:
            continue
        # s = stripline[:len(nGram)] #you only use this once
        # you don't need to check that stripline is of length again; you already did that
        # also, you can just use `endswith` instead of slicing
        if stripline.endswith(nGram):
            words.append(stripline)
    return words

而且,没有 cmets:

def getNGramBeginsWords(nGram, length):
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in wlist:
        stripline = line.strip() # you keep doing this
        # you can merge these two ifs
        if len(nGram)>len(stripline) or len(stripline)!= length:
            continue
        if stripline.endswith(nGram):
            words.append(stripline)
    return words

合并两个相邻的 if:

def getNGramBeginsWords(nGram, length):
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    for line in wlist:
        stripline = line.strip().upper() # you keep doing this
        # you can merge these two ifs
        # also this renders the comparison of ngram and stripline lengths redundant
        if (len(stripline) == length) and stripline.endswith(nGram):
            words.append(stripline)
    return words

现在,让我们看看最后一个版本 - 有趣的是,您实际上从未对 length 执行过数字运算。鉴于长度应该是一个数字,您可能希望将其强制为一个数字;如果无法转换,则会出现异常。

def getNGramBeginsWords(nGram, length):
    wlist = open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r')
    nGram = nGram.upper()
    words = []
    length = int(length) # force to an int
    assert isinstance(n, int) # or do this if you prefer to get an exception on all invalid input
    for line in wlist:
        stripline = line.strip().upper() # you keep doing this
        # you can merge these two ifs
        if (len(stripline) == length) and stripline.endswith(nGram):
            words.append(stripline)
    return words

最后,您永远不会真正明确地关闭文件。你会让它闲逛一段时间。最好使用with 构造来自动关闭它:

def getNGramBeginsWords(nGram, length):
    with open('/home/will/workspace/Genie/src/resources/TWL06.txt', 'r') as wlist:
        nGram = nGram.upper()
        words = []
        length = int(length) # force to an int
        assert isinstance(n, int) # or do this if you prefer to get an exception on all invalid input
        for line in wlist:
            stripline = line.strip().upper() # you keep doing this
            #you should be using `endswith` instead of the slice
            if (len(stripline) == length) and stripline.endswith(nGram):
                words.append(stripline)
        return words

【讨论】:

  • 谢谢,除了“stripline.endsWith(nGram)”之外,我进行了您推荐的大部分更改,而我希望它是 beginWith。问题是我正在向 numLetters 中“添加”值使用“raw_input()”而不先转换为整数,我太习惯于 java 中的 Scanner.nextInt()。抱歉所有愚蠢的错误,感谢您帮助我修复它们!
  • @Thatsillogical 不客气。如果这个回答对你帮助最大,欢迎采纳。
猜你喜欢
  • 2013-05-31
  • 1970-01-01
  • 2022-01-14
  • 2011-09-10
  • 2015-08-31
  • 1970-01-01
  • 2014-05-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多