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
中定义。在函数实际运行一次之前,变量是否未定义?还是在那次奔跑中?
答案 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