constructor classmethods
Ethan Furman
ethan at stoneleaf.us
Thu Nov 3 10:45:28 EDT 2016
On 11/03/2016 01:50 AM, teppo.pera at gmail.com wrote:
> The guide is written in c++ in mind, yet the concepts stands for any
> programming language really. Read it through and think about it. If
> you come back to this topic and say: "yeah, but it's c++", then you
> haven't understood it.
The ideas (loose coupling, easy testing) are certainly applicable in Python -- the specific methods talked about in that paper, however, are not.
To go back to the original example:
def __init__(self, ...):
self.queue = Queue()
we have several different (easy!) ways to do dependency injection:
* inject a mock Queue into the module
* make queue a default parameter
If it's just testing, go with the first option:
import the_module_to_test
the_module_to_test.Queue = MockQueue
and away you go.
If the class in question has legitimate, non-testing, reasons to specify different Queues, then make it a default argument instead:
def __init__(self, ..., queue=None):
if queue is None:
queue = Queue()
self.queue = queue
or, if it's just for testing but you don't want to hassle injecting a MockQueue into the module itself:
def __init__(self, ..., _queue=None):
if _queue is None:
_queue = Queue()
self.queue = _queue
or, if the queue is only initialized (and not used) during __init__ (so you can replace it after construction with no worries):
class Example:
def __init__(self, ...):
self.queue = Queue()
ex = Example()
ex.queue = MockQueue()
# proceed with test
The thing each of those possibilities have in common is that the normal use-case of just creating the thing and moving on is the very simple:
my_obj = Example(...)
To sum up: your concerns are valid, but using c++ (and many other language) idioms in Python does not make good Python code.
--
~Ethan~
More information about the Python-list
mailing list