0xPaige
0xPaige

Reputation: 21

Python, main method not running (multiple classes in same file)

Context: I developed a python script to be run on a remote linux server. Running using Python 3.6.1. The script worked but was very messy, and procedurally written as opposed to OO. So, I re-wrote this script into 2 different classes. One main class and a blueprint class for objects.

My script is a lot more complicated, i just simplified it for this question.

Desired Function: Read values from CSV file. Create Objects from these values, 1 object per line. Do some calculations on the values on init'ing the object (in the objects class). Have these objects be accessible from the main class (Base class).

Problems: I need some clarification on:

  1. The main method is not running. Tried variants on the method call, like Base.main(), including the "if name" statement inside the Base class, and it complains about self not being defined
  2. The "self" reference. Are my usages of this correct? For example: Adding the attribute "age" into the Person objects so you can access it with person.age for example. My method call "self.input_file_handling(Base.inputFilePath)" etc.

Script:

import csv

class Person:
    def calculate_age(self):
        self.age = 2017 - self.birthYear

    def __init__(self, name, birthYear):
        self.name = self.strip_characters(self, name)
        self.birthYear = int(birthYear)
        self.calculate_age()

class Base:

    inputFilePath = "input.csv"
    people  = []
    def main():
        self.input_file_handling(Base.inputFilePath)
        #More methods here

    @staticmethod
    def input_file_handling(input_file_path):

        input_file_path = str(input_file_path)

        with open(input_file_path, 'r') as csv_file:
            csv_reader = csv.DictReader(csv_file)

            for line in csv_reader:
                    name = line['Name']
                    age = line['age']
                    person = Person(name, age)
                    people.append(person)
    
if __name__ == '__main__':
    main()

Upvotes: 0

Views: 2897

Answers (3)

Adirio
Adirio

Reputation: 5286

Your code written in a Pythonic way would be: (Python3)

import csv
from time import time, gmtime


INPUT_FILE_PATH = "input.csv"


class Person:
    def __init__(self, name, birth_year):
        self.name = name.strip()
        self.birth_year = birth_year

    @property
    def birth_year(self):
        return self._birth_year

    @setter.birth_year
    def birth_year(self, value):
        self._birth_year = value
        self._age = gmtime(time()).tm_year - value

    @property
    def age(self):
        return self._age

    @setter.age
    def age(self, value):
        self._birth_year = gmtime(time()).tm_year - value
        self._age = value


def input_file_handling(input_file_path):
    people = []
    with open(input_file_path, 'r') as csv_file:
        csv_reader = csv.DictReader(csv_file)
        for line in csv_reader:
            people.append(Person(line['Name'], int(line['age'])))
    return people


if __name__ == '__main__':
    people = input_file_handling(INPUT_FILE_PATH)

You seem to come from a OOP-only language (C# maybe?). Some tips:

  1. Avoid globals when able for variables, use them for function definition, class definition and constants.
  2. Do not use a new class to store functions that do not require it
  3. Use lower case and '' for variable and function names, Use CamelCase for class names, use caps and '' for constants.
  4. Use duck typing: do not check that a argument is of a given type, try to use it as if it was and handle throw exceptions if it isn't.
  5. Properties ar your friends if you want to force a specific bahaviour at getting or setting a class attributes

If you do not understand somehting ask in the comments.

Upvotes: 1

First the main method of Base class is not static because it use the self variable, so is necessary receive that.

If you want call the main method and use the self variable you need make something like that:

class Base:
  def main(self):
    pass

if __name__ == '__main__':
  instance_of_base = Base()
  instance_of_base.main()

You can call the input_file_handling method without using self, because it's static

Base.input_file_handling(Base.inputFilePath)

I think you need learn more about how python resolve static things and the class and object variables.

Upvotes: 2

DeepSpace
DeepSpace

Reputation: 81654

Python is not C. There is no main function that automagically executes.

The main method that you defined is inside Base class, but it doesn't accept an argument for the instance.

Either modify it so it accept it (ie self by the convention) or make it a static method.

Then in if __name__ == '__main__': either use Base().main() or Base.main(), depending on what approach you decided to take.

But you don't seem to need any of this, and only doing it for the sake of forcing Python to look/work as other languages (looking at you C++/Java). Python doesn't require you to have a class or a 'main' function/method to execute code.

Upvotes: 1

Related Questions