【问题标题】:Undefined variable using decorators使用装饰器的未定义变量
【发布时间】:2018-05-03 10:01:57
【问题描述】:

我正在尝试编写一个代码,允许人们输入坐标或位置,然后返回地点的名称或地点的坐标,这显然取决于用户首先选择输入的内容。我遇到以下错误的错误:NameError: name 'search_lan' is not defined 错误出现在 some_funcion()url 变量

import json
import requests

def my_decorator(some_function):
    def wrapper():
        question = input("Would you like to input coordinates or location?")
        if question == 'coordinates':
            search_lan = input("Input latitude: ")
            search_lon = input("Input longtitude: ")
        elif question == 'location':
            search_place = input("Input address: ")
        else:
            print("Wrong input")
        some_function()

        return search_place, search_lan, search_lon
    return wrapper

api_key = 'api_key_here'




@my_decorator
def some_function():
   url = requests.get('https://maps.googleapis.com/maps/api/geocode/json? 
   latlng={},{}&key={}'.format(search_lan,search_lon,api_key))

   data = json.loads(url.content)

   formatted_address = data['results'][0]['formatted_address']
   print(formatted_address)

some_function()

【问题讨论】:

  • 插入一个 search_lan=search_lon=search_place="" 作为 wrapper() 的第一行,这样无论输入如何,这些变量都有一个值。

标签: python python-3.x decorator nameerror


【解决方案1】:

让我们分解代码的范围。

# Scope: global
import json
import requests

def my_decorator(some_function):
    # Scope: global > my_decorator
    def wrapper():
        # Scope: global > my_decorator > wrapper
        question = input("Would you like to input coordinates or location?")
        if question == 'coordinates':
            search_lan = input("Input latitude: ")
            search_lon = input("Input longtitude: ")
        elif question == 'location':
            search_place = input("Input address: ")
        else:
            print("Wrong input")
        some_function()

        return search_place, search_lan, search_lon
    return wrapper

api_key = 'api_key_here'


@my_decorator
def some_function():
    # Scope: global > some_function
    url = requests.get('https://maps.googleapis.com/maps/api/geocode/json? 
    latlng={},{}&key={}'.format(search_lan,search_lon,api_key))

    data = json.loads(url.content)

    formatted_address = data['results'][0]['formatted_address']
    print(formatted_address)

some_function()

search_lansearch_lon 变量(有时)定义在 global > my_decorator > wrapper 范围内。您尝试在 global > some_function 范围 中使用它们,这不是第一个范围的子范围。这意味着这些变量没有定义。

您可能想要做的是将装饰器包装器中定义的变量传递给装饰函数。

import json
import requests

# fn is the decorated function, in this case fn.
def my_decorator(fn):
    def wrapper():
        question = input("Would you like to input coordinates or location?")
        # Make sure these variables are always defined, as they are used later.
        search_lan = None
        search_lon = None

        if question == 'coordinates':
            search_lan = input("Input latitude: ")
            search_lon = input("Input longtitude: ")
        elif question == 'location':
            # This is not handled, but you’ll get the idea.
            search_place = input("Input address: ")
        else:
            print("Wrong input")
        return fn(search_lan, search_lon)
    return wrapper

api_key = 'api_key_here'


# search_lan and search_lon are passed by my_decorator.
@my_decorator
def some_function(search_lan, search_lon):
    url = requests.get('https://maps.googleapis.com/maps/api/geocode/json? 
    latlng={},{}&key={}'.format(search_lan,search_lon,api_key))

    data = json.loads(url.content)

    formatted_address = data['results'][0]['formatted_address']
    print(formatted_address)

some_function()

【讨论】:

  • 我是个假人。没有意识到装饰器是一回事……尽管 +1
【解决方案2】:

问题是search_lan = input("Input latitude: ") 不会总是被执行,例如他们输入location 或无效输入。

【讨论】:

  • 即使我让它始终执行,我也会遇到同样的错误。
猜你喜欢
  • 2020-01-31
  • 2017-05-07
  • 2016-06-09
  • 2022-07-21
  • 1970-01-01
  • 2020-06-30
  • 1970-01-01
  • 2022-01-16
  • 2013-02-06
相关资源
最近更新 更多