Reputation: 107
I have some python 3.4 code that works fine:
def run():
m = 0
while m != 1:
p = input('Please choose p: ')
p = makeInt(p)
#Some other code
print(p)
m = makeInt(input('Enter 1 if you would like to quit: '))
def makeInt(i):
try:
i = int(i)
except ValueError:
i = input('Incorrect input! Enter your answer: ')
i = makeInt(i)
return i
#Some other functions
if __name__ == '__main__':
run()
I want to put all this code in a class (Except possibly if __name__ ==
...) When I put all the code including if __name__ ==
... in a class like so:
class Foo(object):
def run(self):
m = 0
while m != 1:
p1 = input('Please choose p: ')
p1 = self.makeInt(p1)
#Some other code
print(p1)
m = self.makeInt(input('Enter 1 if you would like to quit: '))
def makeInt(self, i):
try:
i = int(i)
except ValueError:
i = input('Incorrect input! Enter your answer: ')
i = self.makeInt(i)
return i
#Some other functions and stuff
if __name__ == '__main__':
run()
I get the following error: TypeError: run() missing 1 required positional argument: 'self'
. When I remove the self argument from run()
it runs until makeInt()
is called and then I get: NameError: name 'makeInt' is not defined
. I get the same error if I take the if statement out of the class and call Foo.run()
. I have some other code earlier in this program that works when I call functions of a class from another function in that same class. I realize I don't have to put all my code in a class, but in this case I want to. Why am I getting these errors and what can I do to put my working code in a class?
Upvotes: 2
Views: 27168
Reputation: 59238
Since you wrap your code within a class, your run()
is a method now. You should remove your main
from your class by unindenting it and initialize an instance of your class:
if __name__ == '__main__':
Foo().run()
Upvotes: 3
Reputation: 3647
As others mentioned, by putting your functions in a class, you've made them methods, that means they need an instance of this class as first argument. So you can indeed call your run
method using Foo().run()
as Foo()
will create an instance of Foo
.
Another way (e.g. if you don't need the class for anything else than encapsulation) is to make them static, using the staticmethod
decorator:
class Foo(object):
@staticmethod
def run():
...
@staticmethod
def makeInt(i):
...
if __name__ == '__main__':
Foo.run() # don't need an instance as run is static
In Python, a method can be static, i.e. no need for any special argument, a class method, i.e. first argument is the class itself, or a standard method, i.e. the first argument is an instance of the class.
Upvotes: 4
Reputation: 940
It thinks the guard is a part of your class due to the indentation: you have your guard indented to the same level as the other class members. Unindent the
if __name__ == '__main__'
Also change it to be
if __name__ == '__main__':
main()
and then instantiate a new object of type Foo in your newly created main() function
def main():
newFoo = Foo()
newFoo.run()
Upvotes: 0