I'm asking this question with regards to Python, though it's probably applicable to most OOP languages.
When I only expect to use the data model only once in any program, I could either make a class with class/static methods and attributes or just make a regular class and instantiate it once and only use that one copy. In this case, which method is better and why?
With python, I could also write a module and use it like I would a class. In this case, which way is better and why?
Example: I want to have a central data structure to access/save data to files.
Module way:
data.py
attributes = something
...
def save():
...
main.py
import data
data.x = something
...
data.save()
Class way:
class Data:
attributes = something
@classmethod
def save(cls):
Data.x = something
Data.save()
instance way
class Data:
def save(self):
data = Data()
data.x = something
data.save()
Class methods don't need a class instance. They can't access the instance ( self ) but they have access to the class itself via cls . Static methods don't have access to cls or self . They work like regular functions but belong to the class's namespace.
The __new__ method is called with the class as its first argument; its responsibility is to return a new instance of that class. Compare this to __init__ : __init__ is called with an instance as its first argument, and it doesn't return anything; its responsibility is to initialize the instance.
A program may create many objects of the same class. Objects are also called instances, and they can be stored in either a named variable or in an array or collection. Client code is the code that uses these variables to call the methods and access the public properties of the object.
A module is meant to enclose common structures in a "namespace". But really in python a module is just a file and you can organize them however you want. Some people put a lot of functionality in one module. Some people spread them out over packages or sub-packages. Depends on the reusability you want. If a module has a ton of dependencies and you will want to reuse just a small amount, it makes sense to split them.
A class allows you to define types that can be inherited as sub-types. They also let you define a state with each instance of that class.
When your class has no state, and only staticmethods/classmethods, chances are you don't need a class. You just need functions.
Also, you can't create a module and use it like a class. A module can't have subclasses. They just have a basic module init once on load and then a scope of objects.
If what you are after are constants, meaning they are defined once for the life of the app, then just create a constants.py module with a bunch of primitive types like strings, dicts, and lists.
The standard random module implementation has a good design that shows both module level instance creation and use without forcing a singleton on any user.
For example if I call random.random()
it uses a hidden instance of class Random which was initialized at import time. If I'm not satisfied with the default, I can
my_random = random.Random()
my_random.seed('not needed but illustrative seed call')
coin_toss = my_random.random()
and then have a generator that doesn't share state with the hidden instance. If you are interested in this approach, read random.py
which is very well documented; there are only a few relevant lines of code which aren't all that tricky.
This approach gives an interesting, Pythonic twist on singletons: build one on import automatically but don't prevent me from instantiating more if I want.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With