将子程序中的变量全局化为另一个子程序

时间:2015-04-17 14:02:34

标签: python python-3.x python-3.3 subroutine nameerror

将子变量中的变量传递到另一个子程序时遇到了一些麻烦。

以下是代码:

def loop1():
    try:
        age=int(input("How old are you? "))
    except ValueError:
        print ("Please enter a numerical integer of your age. For example: 19 ")
        print("")
        loop1()
    if age>0:
        program()

def program():
    print("")
    print("[1] - Knife / Spray Paint / Lottery Ticket ")
    print("[2] - Alcohol / Tobacco ")
    print("[3] - Anything else ")
    print("")
    loop2()

def loop2():
    try:
        item=int(input("What would you like to buy from the options above? "))
        print("")
    except ValueError:
        print ("Please enter a numerical integer of your item. For example (if you wanted to buy alcohol): 2 ")
        print("")
        loop2()
    if item>0:
        validation()

def validation(): 
    if item == 1 and 16>age :
        print("Sale Denied - Item cannot be sold to Under 16s. ")
    elif item == 1 and 16<age:
        print("Sale Accepted. ")

    elif item == 2 and 18>age:
        print("Sale Denied - Item cannot be sold to Under 18s. ")
    elif item == 2 and 25>age>18:
        print("Check ID before selling alcohol - Challenge 25. ")
    elif item == 2 and 18<age:
        print("Sale Accepted. ")

    elif item == 3:
        print("Sale Accepted. ")

loop1()

结果如下:

How old are you? 21

[1] - Knife / Spray Paint / Lottery Ticket 
[2] - Alcohol / Tobacco 
[3] - Anything else 

What would you like to buy from the options above? 2

Traceback (most recent call last):
  File "D:/Shop Program.py", line 48, in <module>
    loop1()
  File "D:/Test.py", line 9, in loop1
    program()
  File "D:/Shop Program.py", line 17, in program
    loop2()
  File "D:/Shop Program.py", line 28, in loop2
    validation()
  File "D:/Shop Program.py", line 33, in validation
    if item == 1 and 16>age :
NameError: global name 'item' is not defined

正如您从上面的错误消息中看到的那样,它是global name 'item' is not defined。我试图将global item放在def vaildation():之上,但我仍然会遇到同样的错误。

3 个答案:

答案 0 :(得分:2)

而不是使用global,这是bad practice(在Python和其他地方),明确地将itemloop2传递到validation

def loop2(age):
    ...
    if item > 0:
        validation(item, age)
                 # ^ pass it here

def validation(item, age): 
             # ^ receive it here
    if item == 1 and 16 > age:
        ...

请注意,我对age做了类似的事情,应该在调用loop2时传入。使用递归进行输入验证并不理想;请参阅Asking the user for input until they give a valid response了解替代方法。

答案 1 :(得分:0)

如果您已经知道这一点,请原谅我,但还有另一种方法可以让该项进入validate子程序,这对您来说可能更有效。您可以将变量“传入”子例程(也称为方法或函数)。您“传入”到子例程的变量称为参数。 要使用子程序参数,您必须做两件事:

  1. 在子程序定义中定义参数
  2. 在调用子例程时将变量指定为“传入”
  3. 因此,对您而言,在item例程中定义参数validate将如下所示:

    def validate(item):
        if item == 1 and 16>age :
    

    看看我如何在括号之间插入item

    然后,您所要做的就是将项目“传入”验证功能:

    def loop2():
    try:
        item=int(input("What would you like to buy from the options above? "))
        print("")
    except ValueError:
        print ("Please enter a numerical integer of your item. For example (if you wanted to buy alcohol): 2 ")
        print("")
        loop2()
    if item>0:
        validation(item)
    

    注意我如何在最后一行调用item子例程的括号之间放置validation

    希望有所帮助

答案 2 :(得分:0)

除了你原来的问题:如果异常上升,loop1和loop2中可能会有无限递归,因为函数会自行调用。

更好的方法是在成功转换后使用循环(而True:...)。

此外,在每种编程语言中,以您的方式链接功能是不好的做法。这比使用goto更糟糕,通常被称为意大利面条代码。 更好的方法是使用一个main函数连续调用函数,并将前一个函数的结果作为参数传递给下一个函数:

age = get_age()
item = get_item()
if age < 16 and item == ...:
    print("Not allowed")
...

更好的方法是使用{&#34; item&#34; :minimal_age}:

items = { "butter": 0 , "knife": 16, "booze": 18, "beer": 17 }

age = ...
item = get_item(items)    # the list can be built automatically from dict
if age < items[item]:
    print("Too young for", item)
else:
    purchase(item)

这样可以避免if ... elif ..测试的loooooong列表。 如果通过字符串而不是数字来标识项目,则会增加可读性。一般来说,在Python中,numberincal值只能在它们是&#34; natural&#34;的地方使用,否则使用适当的类型,如字符串,集合等。 请注意,这与其他语言(例如C)不同,其中字符串处理非常不舒服且昂贵。