变量未定义,函数定义包含变量?

时间:2014-04-30 03:54:28

标签: python

sequence = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'


def caesar( original, variationShift):
    '''returns: a version of original created by replacing each letter with 
       the letter "variationShift" units later in the alphabet sequence.
       If variationShift is negative, replacing letter is found earlier in  
       alphabet.'''
    index = 0
    result = ''
    while index < len( original):
        lookFor = original[ index]
        foundAt = sequence.find( lookFor)
        if foundAt == -1:
            # untranslatable character
            result += lookFor
        else:
            result += sequence[ variationShift]  # negative indexes OK!

        index += 1
    return result

def encryptCaesar (original):
    caesar( original, foundAt - 3)
    return result

def decryptCaesar (original):
    caesar( original, (foundAt + 3) % len(sequence))
    return result

变量foundAt经常被认为是未定义的。然而,它在caesar中定义。在函数实际运行一次之前,变量是否未定义?还是在那次奔跑中?

3 个答案:

答案 0 :(得分:2)

其他答案解释了变量范围,但您有一些更基本的问题。您正在混合使用这些变量的位置。你想做的就是通过轮班。您不知道调用点的foundAt位置,该位置是在循环中计算的。另一个问题是返回值。您需要从caesar()返回值。下面的代码执行标准的caesar加密和解密。

sequence = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

def caesar( original, variationShift):
    '''returns: a version of original created by replacing each letter with 
       the letter "variationShift" units later in the alphabet sequence.
       If variationShift is negative, replacing letter is found earlier in  
       alphabet.'''
    index = 0
    result = ''
    while index < len( original):
        lookFor = original[ index]
        foundAt = sequence.find( lookFor)
        if foundAt == -1:
            # untranslatable character
            result += lookFor
        else:
            result += sequence[ (foundAt + variationShift) % len(sequence)]
        index += 1
    return result

def encryptCaesar (original):
    return caesar( original, -3)

def decryptCaesar (original):
    return caesar( original, 3)

答案 1 :(得分:0)

在执行函数之前,函数定义中的所有代码都不会实际运行。

此外,函数内定义的变量仅在函数中有效。引用A Guide to Python namespaces

  

在任何时候都有许多作用域:你所在的当前函数的作用域,模块的作用域以及Python内置函数的作用域。这种范围嵌套意味着一个函数无法访问另一个函数内的名称。

foundAt是在函数名称空间(caesar的名称空间)内定义的变量的示例。 sequence是模块名称空间内定义的变量的示例。因此,您可以访问sequence内的caesar和其他功能,但无法在foundAt之外访问caesar

如果希望foundAt可以在encryptCaesar内访问,则需要将其作为参数传递,或者在encryptCaesar的父名称空间中声明它(模块名称空间) - 或者,您可以在encryptCaesar中定义caesar并通过闭包访问父函数中定义的变量。在大多数情况下,将其作为参数传递给你的是什么。

答案 2 :(得分:0)

由于函数的范围,foundAt是仅在caesar函数中找到的局部变量。要解决这个问题,请使用global变量:

>>> def foo():
...     global oof
...     oof = 9
... 
>>> oof
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'oof' is not defined
>>> def boo():
...     global oof
...     oof+=1
... 
>>> global oof
>>> foo()
>>> oof
9
>>> boo()
>>> oof
10
>>> 

在您的代码中:

sequence = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'


def caesar( original, variationShift):
    global foundAt
    '''returns: a version of original created by replacing each letter with 
       the letter "variationShift" units later in the alphabet sequence.
       If variationShift is negative, replacing letter is found earlier in  
       alphabet.'''
    index = 0
    result = ''
    while index < len( original):
        lookFor = original[ index]
        foundAt = sequence.find( lookFor)
        if foundAt == -1:
            # untranslatable character
            result += lookFor
        else:
            result += sequence[ variationShift]  # negative indexes OK!

        index += 1
    return result

def encryptCaesar (original):
    global foundAt
    caesar( original, foundAt - 3)
    return result

def decryptCaesar (original):
    global foundAt
    caesar( original, (foundAt + 3) % len(sequence))
    return result