Reputation: 4378
I have a class and some methods in that class which I want to reference using a dictionary inside the class. If I define the dictionary before the class method I get a "not defined error". However, if I put the dictionary after the method definition python does not complain. Why is that? And what can I do to fix it?
Code example:
This does not work
class foo:
fooFunDic = {
'fooFun1': fooFun1,
'fooFun2': fooFun2
}
def fooFun1(self):
return 0
def fooFun2(self):
return 0
Ugly but works
class foo:
def fooFun1(self):
return 0
def fooFun2(self):
return 0
fooFunDic = {
'fooFun1': fooFun1,
'fooFun2': fooFun2
}
Upvotes: 1
Views: 209
Reputation: 5061
When you assign a variable python serach that variable in 1:-Local namespace then serach in gloabal namespace. Python at compile time compiled the code line by line hence first line compile first, if any undefined variable came NameError: name 'fooFun1' is not defined
.
in your case what python does, it looks for dictionary values but they are not defined untill parsing the dict.
The main thing in python is it parse the code line by line hence begore using any variable you have to assign it.
Upvotes: -1
Reputation: 1488
Define init and pass fooFun1() and fooFun2() in it.
class foo:
def __init__ (self, fooFun1, fooFun2):
fooFunDic = {
'fooFun1': fooFun1,
'fooFun2': fooFun2
}
def fooFun1():
return 0
def fooFun2():
return 0
This way you can run these functions without defining them before. This is the good way to do. By doing this Python will not be dependent on these fooFun1() and fooFun2() and run successfully (though you might need them to add some functionality). This will be useful if you later want to change the name of the input functions or you want to add some functionality.
Upvotes: 0
Reputation: 31270
The reason is that Python is an interpreted language, and all the code class
statement is executed when the class statement is.
You can add some print
statements in the class definition to see it in action.
So if fooFunDic
is early in the class definition, it's executed at a time when the methods simple don't exist yet.
Upvotes: -1
Reputation: 1123420
The names are yet do be defined when you define the dictionary.
The class body is executed like a function and the local namespace forms the attributes. The same order of name definition applies therefor.
Note that even in your second example, what you store in the dictionary are functions, not methods. Calling those functions would require you to explicitly pass in self
parameters if you want them to work like methods. You could define the dictionary in the __init__
method instead to get bound methods in a dictionary stored on the instance:
class foo:
def __init__(self):
self.fooFunDic = {
'fooFun1': self.fooFun1,
'fooFun2': self.fooFun2
}
def fooFun1(self):
return 0
def fooFun2(self):
return 0
If you don't care about bound methods vs. bare function objects, you can define the dictionary first, then 'register' each function with that dictionary:
class foo:
fooFunDic = {}
def fooFun1(self):
return 0
fooFunDic['fooFun1'] = fooFun1
def fooFun2(self):
return 0
fooFunDic['fooFun2'] = fooFun2
Upvotes: 3
Reputation: 658
Do you need that dict to be a static variable?
You could do:
class foo:
def __init__(self):
self.fooFunDic = {
'fooFun1': self.fooFun1,
'fooFun2': self.fooFun2
}
def fooFun1:
return 0
def fooFun2:
return 0
Upvotes: 0