Replies: 1 comment 1 reply
-
Hey @a-r-j! Thanks for the tag 😄. I gave the idea a bit of thought, and here are some of my preliminary conclusions. The design of NetworkX's API I think follows the idea of having a class to hold data and state, class methods that manipulate state, and a collection of functions that calculate something based on that class' state. Riffing off the three example classes of functions that you've got, I think they may more naturally fall under the category of functions that calculate something based on a NetworkX graph's state. If namespacing the functions under a single class is something desirable, the functional programming-style alternative would be to namespace all of the functions in graphein's top-level API, perhaps? You'd be able to do a pattern like: import graphein
G = nx.Graph(...)
result = graphein.some_function(G)
another = graphein.another_function(G)
# and for functions that return graphs
subG = graphein.extract_subgraph(G, *args, **kwargs) This is something that NetworkX does as well, so almost all functions can be accessed under Another thing I've heard through the programmer's grapevine is to "optimize for composability rather than inheritance". (I think if you Google that phrase itself you might find some good PyCon talks on the topic.) Having been convinced by the idea, I've personally avoided classes except as a data structure to hold related collections of information together. One other idea to chew on: a class would be useful if you did the method chaining pattern prevalent in the PyTorch and pandas world. That is, an object always returning self except for terminal class methods that return a different data structure. Method chaining gives rise to "fluent" programming, which could be nice. Hope this gives you something to chew on! 😄 I am sensing that the design decision, once made now, may end up persisting for a while and could be difficult to roll back later. My current understanding of the graphein codebase would lead me to suggest that you could delay subclassing for a bit by experimenting with a comprehensive top-level API and see how that works. There may be some programmatic way to attach functions as class methods, which is what we do with pyjanitor for pandas DataFrames (it's a bit magical and bespoke for pandas), which would let you leverage functions already written while giving the class-based fluent programming idea. |
Beta Was this translation helpful? Give feedback.
-
I want open up a discussion on subclassing
nx.Graph
in order to simplify some of the utilities. As a concrete example:I think in this way we preserve all of the features of & compatibility with NetworkX but could make for a substantially cleaner and more intuitive API. Is there any obvious drawback to this I might be missing?
@ericmjl would be super appreciative of any thoughts :)
Beta Was this translation helpful? Give feedback.
All reactions