0

I'm new to python web development (and OOP in general). I have a view in my data base that consists of 7 "parts", and I wanted to divide them into their own classes (though the data is "joined" in my database). The parts/classes would be TrainerData, Pokemon1, Pokemon2, etc...

Here's a more simple version of what i'm going for. I know the issue and error, I just don't have the knowledge to solve this one. Here's what I have so far.

import psycopg2

class Trainer:
    def __init__(self):
        self.trainerdata = self.TrainerData()

    class TrainerData:
        def __init__(self, trainername, battle, winnings):
            self.trainername = trainername
            self.battle = battle
            self.winnings = winnings

        @classmethod
        def load_from_db_by_tname(cls, tname):
            with psycopg2._connect(user='postgres', password='samfurdissamrea', database='ODS', host='localhost') as connection:
                with connection.cursor() as cursor:
                    cursor.execute('SELECT trainer_name, battle, winnings from public.poke_data_web WHERE lower(trainer_name) = lower(%s)', (tname,))
                    trainer_data = cursor.fetchone()
                    return cls(trainername=trainer_data[0], battle=trainer_data[1], winnings=trainer_data[2])


a = Trainer()
print(a.trainerdata.load_from_db_by_tname('angus'))

The error returned:

Traceback (most recent call last):
  File "C:/Users/ageeray/Documents/Python Scripts/PokeTrainerWeb/trainer.py", line 22, in <module>
    a = Trainer()
  File "C:/Users/ageeray/Documents/Python Scripts/PokeTrainerWeb/trainer.py", line 5, in __init__
    self.trainerdata = self.TrainerData()
TypeError: __init__() missing 3 required positional arguments: 'trainername', 'battle', and 'winnings'

I can get this to work if I don't have the TrainerData as a nested class, but otherwise, I've hit a wall. All input is appreciated; thank you for your time.

4
  • The code shown in the traceback does not match the code above it. Please show us the code you're actually running and the error message it produces. Commented Oct 20, 2018 at 21:52
  • 1
    It should be a = Trainer(Trainer.TrainerData.load_from_db_by_tname('angus')), but I find it rather strange that you use nested classes anyway, why is this useful here? Commented Oct 20, 2018 at 21:53
  • @WillemVanOnsem tbh, i'm not quite sure. I just thought that this would be the logical way to organize my classes, but maybe i'm wrong. I guess I could break out the nested classes into their own, non nested classes, but I wasn't sure how to make them "join"/ depend on one another. Commented Oct 20, 2018 at 21:55
  • No, nested classes are rarely useful in Python. Your classes here would work exactly the same, you just wouldn't refer to it with self Commented Oct 20, 2018 at 21:59

1 Answer 1

1

It seems your inner class TrainerData requires 3 arguments trainername, battle, winnings which you listed as arguments in class __init__ function.

However, you are trying to create an object of TrainerData in the main class without any arguments

self.trainerdata = self.TrainerData()

This actually triggered your problem. You need to provide 3 arguments for this nested class.

self.trainerdata = self.TrainerData('John', 'StackOverflow', +10)

BTW you can also specify default arguments for __init__ function:

   class TrainerData:
        def __init__(self, trainername="nobady", battle="any", winnings=0):
            self.trainername = trainername
            self.battle = battle
            self.winnings = winnings

In this case, you actually can create an object of this class without arguments. It would set a default argument for any missed one. For example, all below would perfectly work in this case

self.trainerdata = self.TrainerData()
self.trainerdata = self.TrainerData(trainername="John")
self.trainerdata = self.TrainerData(trainername="John", battle="StackOverflow")
self.trainerdata = self.TrainerData(trainername="John", winnings=100)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.