简体   繁体   中英

Undefined variable using decorators

I am trying to write a code that will allow person to enter either coordinates or location, which then would return either name of the place or coordinates of the place, obviously depending on what user chose to enter first. The error I came across following error: NameError: name 'search_lan' is not defined Error comes up under some_funcion() on url variable

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()

Lets break down the scopes of your code.

# 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()

The search_lan and search_lon variables are (sometimes) defined in the global > my_decorator > wrapper scope. You're trying to use them in the global > some_function scope , which is not a child scope of the first one. This means those variables are not defined.

What you probably want to do is pass the variables defined in the decorator wrapper into the decorated 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()

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM