Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Class with many attributes, what would be the 'right' way to do this?

What is the ‘correct’ or ‘right’ way to handle classes with many attributes? I have a class with 37 attributes and it seems quite excessive and not practical.

This class is going to be used to handle inserting this data to a database, retrieve that information from a database and its also going to be used to run some mathematic models.

I thought about putting all that information to a dictionary but accessing these attributes might be easier and clearer if they are attributes rather than if they would be in a dictionary.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

What are your thoughts on this? Down below is the class and its init method.

class Statistics:

    def __init__(self, match_id,
                home_ball_possession = None,      away_ball_possession = None,
                home_goal_attempts = None,        away_goal_attempts = None,
                home_shots_on_goal = None,         away_shots_on_goal = None,
                home_shots_off_goal = None,        away_shots_off_goal = None,
                home_blocked_shots = None,        away_blocked_shots = None,
                home_free_kicks = None,           away_free_kicks = None,
                home_corner_kicks = None,         away_corner_kicks = None,
                home_offsides = None,            away_offsides = None,
                home_throw_ins = None,            away_throw_ins = None,
                home_goalkeeper_saves = None,     away_goalkeeper_saves = None,
                home_fouls = None,               away_fouls = None,
                home_red_cards = None,            away_red_cards = None,
                home_yellow_cards = None,         away_yellow_cards = None,
                home_total_passes = None,         away_total_passes = None,
                home_completed_passes = None,     away_completed_passes = None,
                home_tackles = None,             away_tackles = None,
                home_attacks = None,             away_attacks = None,
                home_dangerous_attacks = None,    away_dangerous_attacks = None
             ) -> None:
    
    self.match_id = match_id

    self.home_ball_possession = home_ball_possession
    self.away_ball_possession = away_ball_possession
    
    self.home_goal_attempts = home_goal_attempts
    self.away_goal_attempts = away_goal_attempts

    self.home_shots_on_goal = home_shots_on_goal        
    self.away_shots_on_goal = away_shots_on_goal

    self.home_shots_off_goal = home_shots_off_goal       
    self.away_shots_off_goal = away_shots_off_goal

    self.home_blocked_shots = home_blocked_shots       
    self.away_blocked_shots = away_blocked_shots

    self.home_free_kicks = home_free_kicks          
    self.away_free_kicks = away_free_kicks

    self.home_corner_kicks = home_corner_kicks        
    self.away_corner_kicks = away_corner_kicks

    self.home_offsides = home_offsides           
    self.away_offsides = away_offsides

    self.home_throw_ins = home_throw_ins           
    self.away_throw_ins = away_throw_ins

    self.home_goalkeeper_saves = home_goalkeeper_saves    
    self.away_goalkeeper_saves = away_goalkeeper_saves

    self.home_fouls = home_fouls              
    self.away_fouls = away_fouls

    self.home_red_cards = home_red_cards           
    self.away_red_cards = away_red_cards

    self.home_yellow_cards = home_yellow_cards        
    self.away_yellow_cards = away_yellow_cards

    self.home_total_passes = home_total_passes        
    self.away_total_passes = away_total_passes

    self.home_completed_passes = home_completed_passes    
    self.away_completed_passes = away_completed_passes

    self.home_tackles = home_tackles            
    self.away_tackles = away_tackles

    self.home_attacks = home_attacks         
    self.away_attacks = away_attacks

    self.home_dangerous_attacks = home_dangerous_attacks 
    self.away_dangerous_attacks = away_dangerous_attacks

Edit: changed attribute names from camelCase to lowercase, with words separated by underscores

>Solution :

Use dataclasses, along with typing.

import dataclasses

@dataclasses.dataclass
class Statistics:
    matchId: X
    homeBallPossession: X
    awayBallPossession: X
    ...

Replace all X‘s with type names, e.g. int, str, typing.Optional[int], and so on.

This way, you don’t have to write out a constructor at all, so you don’t have to repeat every single field three times (once as the parameter and two more times in the assignment): dataclasses does all the boilerplate for you.

You can then use the constructor as you’d expect, with keyword-arguments for each field, as well as assign to (and read) each field in the normal way:

stats = Statistics(matchId=someMatchId, ...)
...
stats.homeBallPossession = someValue
...
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading