简体   繁体   中英

Why is Python reading my function call as a variable call?

Using Python 2.7.9, this is my code:

    def secondaction():
        secondaction = raw_input(prompt)

        if secondaction == "walk through door" or secondaction == "go through door":
        print "Well done! You enter the Treasure Room..."
        treasure_room()

        else:
        print "If you don't go through that door you will never leave this cave."        
        secondaction()

firstact = raw_input(prompt)
global handclenched
def firstaction():
elif firstact == "use sword" and handclenched:
    print "You killed the hand giant! A door appears behind it. What will you do?"
    secondaction()

When Powershell takes me to the secondaction() function after I enter 'use sword' with 'handclenched' set to True , I enter yh as the raw_input() value and Powershell puts forward this error message:

You killed the hand giant! A door appears behind it. What will you do?
> yh
If you don't go through that door you will never leave this cave.
Traceback (most recent call last):
  File "ex36game.py", line 168, in <module>
    right_room()
  File "ex36game.py", line 166, in right_room
    firstaction()
  File "ex36game.py", line 147, in firstaction
    firstaction()
  File "ex36game.py", line 153, in firstaction
    secondaction()
  File "ex36game.py", line 136, in secondaction
    secondaction()
TypeError: 'str' object is not callable

However when I change the code to:

 def secondaction():
    second_action = raw_input(prompt)

    if second_action == "walk through door" or second_action == "go through door":
    print "Well done! You enter the Treasure Room..."
    treasure_room()

    else:
    print "If you don't go through that door you will never leave this cave."        
    secondaction()

It all works fine and I get no error message.

Why can't Python read the secondaction() as a function call instead of code that invokes/calls (are those the correct words?) the secondfunction variable that raw_input() was assigned to?

In Python, functions are objects, and a function name is just a variable that happens to hold a function. If you reassign that name, it isn't holding your function any more.

Because you redeclaring the name secondaction = raw_input(prompt) in local scope.

Take a look at python-scopes-and-namespaces

Because you wrote:

secondaction = raw_input(prompt)

sectionaction is now a string, and you can't call a string as if it were a function. A name can't have two meanings at the same time, and the most recent assignment takes precedence, so you have lost the reference to your function. Use a different name for one of them, as you have done in the code that works.

Why can't Python read the 'secondaction()' as a function call instead of code that invokes/calls (are those the correct words?) the 'secondfunction' variable

In Python, functions are variables. That is to say, functions are first-class objects, which are assigned to variables by the def statement; there is no separate namespace for callable functions vs assignable variables like some languages have.

This means that when you write secondaction = raw_input(prompt) you are making a local variable called secondaction inside the function. Now when you write secondaction anywhere in that function body you are referring to the local variable; writing secondaction() with parentheses doesn't get you access to a separate function namespace, it just tries to call the value of the local variable that secondaction represents, and strings aren't callable so you get an error.

It also means you can do things like:

def foo(x):
    return x+1

>>> bar= foo
>>> lookup= {'thing': bar}
>>> lookup['thing']
<function foo>
>>> lookup['thing'](1)
2

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