将子变量中的变量传递到另一个子程序时遇到了一些麻烦。
以下是代码:
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():
之上,但我仍然会遇到同样的错误。
答案 0 :(得分:2)
而不是使用global
,这是bad practice(在Python和其他地方),明确地将item
从loop2
传递到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
子程序,这对您来说可能更有效。您可以将变量“传入”子例程(也称为方法或函数)。您“传入”到子例程的变量称为参数。
要使用子程序参数,您必须做两件事:
因此,对您而言,在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)不同,其中字符串处理非常不舒服且昂贵。