Q: Proper way to instantiate an object when its content gets parsed from argument I'm working on a class that works with graphs. One of the ways to instantiate such a graph-object is to use a filepath as an constructor argument and the graph structure gets read/replicated from there. To do the actual parsing I use a secondary function.
Which is the correct way to actually set the graph field?
Shortened, assuming magic returns the graph structure:
class Graph:

    def __init__(self, parse):
        self.graph = self._parse_file(parse)

    def _parse_file(file_path):
        return magic(file_path)

or
class Graph:

    def __init__(self, parse):
        self._parse_file(parse)

    def _parse_file(file_path):
        self.graph = magic(file_path)

Does it even matter? It seems to me like I'm missing something.

A: I'd go with the first option for the following reasons:


*

*It clearly separates responsibilities, as your _parse_file method does exactly one thing.  In the second option it does two things: parses the file and updates the instance state.

*It is easier to test.  You can turn _parse_file into a classmethod or a staticmethod and test it separately without the need to create a Graph instance, which becomes more important when Graph.__init__ gets bigger and more complex.

*It protects you from unexpected usage.  Even though _parse_file is prefixed with an underscore, it is still not truly private, so someone might call _parse_file on an existing instance of Graph, which, in the second case, will modify its state, and you probably want to avoid that.


A: You seem to be on OOP track, but here are some doubts: 


*

*Graph.graph is worrying.

*testing: imagine you go about testing the progam at some point - are you willing to construct the graph, dump it to file and then read it from file and check graph from there? Or holding little static graph files as fixtures?

*programs that mix levels of abstraction haunt you (your users or collaborators) at night and turn out very expensive as size/complexity grows. File is a file, data structure is data structure, magic() is your reader. 

*Readability? None of options are particularly to cozy to read. Think of pd.read_csv() - it is a nice filename -> new data structure conversion. pd.Dataframe is also a data structure you can construct out of lists/dict, no need to lock into a file. What makes Graph different? 
In your next round of design review you may consider:


*

*a clean data class to hold your graph internals. It is probably as simple as a dict/json

*file read/file dump functions

*standalone graph transformation funcs

*staying away from classes as long as you can resist

*composing the class out of workable primitives once you opt for it. 

