Read file into list when class is instantiated in Python 2.7 I would like to read a file into a list when I create the class below. Once the list is ready, I would like to access it outside the class in order to process more code based on the list which now contains my file. Can the code be improved upon?

class ReadFile(object):
    def __init__(self, filename):
        self._data = []
        self.localdir = 'C:\\Users\\User\\Documents'
        self.filename = filename
        self.filepath = os.path.join(self.localdir, self.filename)
        self.read_data()

    def read_data(self):
        try:
            with open(self.filepath, 'rU') as c:
                rows = csv.reader(c)
                for row in rows:
                    self._data.append(row)
        except Exception as ex:
            print(ex)

    def get_data(self):
        return self._data

def main():
    new = ReadFile('myfile.csv')
    new_data = new.get_data()

    for i in new_data:
        print(i)        # etc... more code will follow

if __name__ == '__main__':
    main()
I agree with Caridorc about not needing a class, in addition ReadFile isn't a very good class name, it sounds like a function. Unless, you meant read as an adjective (this file has been read), but you can see how that could be confusing.

Keeping filename and your hardcoded path seems redundant at the moment

    self.localdir = 'C:\\Users\\User\\Documents'
    self.filename = filename
    self.filepath = os.path.join(self.localdir, self.filename)


Also you could use r''to write your filepath without the double backslash. r before a string will tell Python to interpret it literally, ie. Don't consider anything an escape character. That means that a backslash will always just be a backslash.

You store all 3 of these but only every use filepath, why not go directly to creating the filepath? The point of init should be taking the passed parameters and turning them into the form needed for your class, and your class only needs filepath. Particularly if you do convert this to a function, it'll become less useful to keep the redundant values.

Also, since init is about getting the data you need, why even have getData as a separate function? Collapse that back into init since it's being called there anyway and will never be called again. In fact if you call get_data() twice you've accidentally doubled up on the info, which you surely never want.

Since you're not changing the data at all, you can pass the csv reader directly to list() to create a list. In fact, you could just return list(rows) if you turned this all into one function. 

You should add a docstring to your class/function. ReadFile seems pretty clear until you find out that you've passed a filepath and gotten an error that it doesn't exist (since you read from a specific directory) or you might be puzzled when you pass a text file and get back a csv formatted file.

Here's how I might refactor your code:

def read_csv_file(filename):
    """Returns a list of data from a csv file passed to it.

    Only reads files from 'C:\Users\User\Documents\' + filename
    Prints any exceptions from reading the file."""

    filepath = os.path.join(r'C:\Users\User\Documents', filename)

    try:
        with open(filepath, 'rU') as c:
            rows = csv.reader(c)
            return list(rows)
    except Exception as ex:
        print(ex)


def main():
    new_data = read_csv_file('myfile.csv')
    for i in new_data:
        print(i)        # etc... more code will follow

if __name__ == '__main__':
    main()


If you were sticking with keeping it a class then I'd still keep the above in one function and make minor other changes. I'd add a docstring about the class's general use.

Also I would no longer catch and print the error. Errors shouldn't be ignored, and failing to read your file will actually mean that the class hasn't been correctly created as it's missing crucial data and likely has an invalid path. You can either let it be normally raised without intervention, or add a custom error message with raise ErrorType("Message about the error"). In your case IOError is likely, so you might raise IOError with a message about how the passed filename isn't in your hardcoded directory. But exactly how you'll handle that is up to you. 

Like this:

class ReadFile(object):
    """Docstring"""

    def __init__(self, filename):
        self.localdir = r'C:\Users\User\Documents'
        self.filename = filename
        self.filepath = os.path.join(self.localdir, self.filename)

        try:
            with open(self.filepath, 'rU') as c:
                rows = csv.reader(c)
                self._data = list(rows)
        except IOError:
            raise IOError("{} not found in {}".format(
                          self.filename, self.directory)
    def get_data(self):
        return self._data