1
# animal.py
class Animal:
    def __init__(self):
        self.action = {'feed':feed_pet}

    def do_action(self, a):
        action[a]()

    def feed_pet(self):
        print('Gives some food')

# main.py
from animal import *
my_pet = Animal()
my_pet.do_action('feed')

I am tyring to make game, but this code gave me the following error:

Traceback (most recent call last):
  File "so.py", line 3, in <module>
    my_pet = Animal()
  File "/home/wdwickar/pyside/animal.py", line 4, in __init__
    self.action = {'feed':feed_pet}
NameError: name 'feed_pet' is not defined

Is there no forward declaration in Python like C ?

Prune
  • 76,765
  • 14
  • 60
  • 81
xiaofo
  • 57
  • 1
  • 2
  • 5
  • Possible duplicate of [Is it possible to forward-declare a function in Python?](https://stackoverflow.com/questions/1590608/is-it-possible-to-forward-declare-a-function-in-python) –  Aug 27 '18 at 16:19
  • 4
    There's no global variable called `feed_pet`. You meant `self.feed_pet`. – Denziloe Aug 27 '18 at 16:19
  • @Kos It's slightly different with classes. That's not an exact duplicate. – AKX Aug 27 '18 at 16:20

4 Answers4

7

The problem is that you did not understand python classes, you are referring to a global scoped name feed_pet but you meant to call the function within the class, for that you need to use self, check the changes below:

class Animal:
    def __init__(self):
        self.action = {'feed':self.feed_pet}

    def do_action(self, a):
        self.action[a]() //use self also for access instance attributes

    def feed_pet(self):
        print('Gives some food')

# main.py
from animal import *
my_pet = Animal()
my_pet.do_action('feed')

For making it clear, Does Python support forward declaration in class?

There is no need for forward declarations in python, unlike C you can redefine any object as many times as you want, python will keep the last one of them as the live ones. Also, as it does not have static typing at compile time, you can use any variable as any type, hence you don't need to declare anything to use it, just at runtime have to be in the same scope.

Netwave
  • 40,134
  • 6
  • 50
  • 93
3

Use self.action = {'feed': self.feed_pet} instead to refer to the bound instance function.

There's no global name feed_pet.

AKX
  • 152,115
  • 15
  • 115
  • 172
0

You left out the required object activation in each of two references. There is no general function feed_pet or variable action. There are instance methods -- so you have to supply the instance in each reference (call). The code below fixes the problem giving the one-line output "Gives some food". Note the two places where I've added self. to the call.

# animal.py

class Animal:
    def __init__(self):
        self.action = {'feed': self.feed_pet}   #  Add "self"

    def do_action(self, a):
        self.action[a]()   #  Add "self"

    def feed_pet(self):
        print('Gives some food')

Also, please note that there is no declaration here, except the one implicit in the function definition. Python just needs you to have the function defined before you call it.

Prune
  • 76,765
  • 14
  • 60
  • 81
0

First clear out some basic concepts:
1. self parameter is reference that points to instance of class.(like this in c++)
2.by using self , we can access attributes and methods of class.
In your code, you refer to global scope variables and methods. Refer class variables and methods using self pointer.
e.g self.action = {'feed': self.feed_pet}