1

I am rewriting a script for Python 3.6 and ArcGIS Pro compatibility and it seems like user defined functions will be necessary to clean it up. I am fairly new. I separated the code block into two functions and I would like to call the first function in the beginning of the second function. I'd also like to call the first function near the bottom but I'm getting a NameError. Here is the code block that I am working on.

def select_address():
    for lyr in m.listLayers():  
        if lyr.name == "LOCATION.addresspoint":
            CoaAddresses = lyr
            selection = arcpy.SelectLayerByAttribute_management(CoaAddresses,"NEW_SELECTION", expression)
            return(selection)

def found_address():
    select_address()
    print(selection)
    for row in arcpy.SearchCursor(selection): #retrieve address of selected feature
        selectedAddress = row.FULL_STREET_NAME  #this variable used later for legend
        return(selectedAddress)

select_address()

results = arcpy.GetCount_management(selection) #return number of features selected

the error I get:

results = arcpy.GetCount_management(selection) #return number of features selected

NameError: name 'selection' is not defined

Shouldn't selection be defined in the def select_address(): portion of the script?

3
  • 1
    Just because Python permits spaghetti code with respect to variable scoping doesn't mean it's good practice. Your code will be far more maintainable if functions which set variables either return the value or modify a list, dictionary, or object which is provided as input. And script modernization is a prime time to eliminate deprecated old-style cursor use in favor of faster, more Pythonic DA cursors.
    – Vince
    Dec 28 '19 at 12:46
  • I want to make sure I understand your advice. I'm not setting any global variables within my functions here, so this block of code is okay? You're referring to setting a global variable inside of a function? Dec 30 '19 at 18:12
  • 1
    You have several maintainability flaws in this script. 1) The layer name is hard-coded in a function 2) select_address returns from inside a loop, so you'll never find an error with duplicate layer names 3) select_address returns a value which is ignored (twice) 4) found_address is defined, but never called 5) found_address ignores the result of select_address 6) You're not using a DA cursor 7) found_address returns from within a cursor, which is never deleted, and for which multiple rows are never tested. Global variables should only be used when it's the only option.
    – Vince
    Dec 30 '19 at 19:04
2

selection is a local variable within select_address(), so you can't use it outside the scope of that function.

selection = select_address() should fix the name error

2
  • Yes, that fixed the NameError. The "expression" variable used in the SelectLayerByAttribute_management function is assigned outside and before the select_address function is defined, is that okay or do I need to assign it inside of the function? Dec 27 '19 at 21:37
  • If its a global variable (i.e. defined outside any other function) you should be able to use it anywhere, including within a function. Some people would probably say this is bad practice and that you should modify the function to only use local variables, taking in any outside information as an argument/parameter. But this probably isn't necessary in your case
    – Nick
    Dec 27 '19 at 21:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.