...
Not exactly. This moves the singleton implementation logic to the module, but doesn't change its general principle. Better than the class, but
not flexible, and hardly testable (think test case interdependencies). It does prove that no Singletons are needed in Python, even if you want to reify the pattern.
What I meant was inverting control: the consumer does not request the resource at run time, but is injected with the resource by its controlling module at construction time. The life of the resource is controlled by the controlling module:
# ui.py - consuming module
classLed:def__init__(self,gpio,pin):# resource is injected!
self.gpio=gpioself.pin=pindefblink(self,times:int):for_inrange(times):self.gpio.pin(self.pin,1)time.sleep(.5)self.gpio.pin(self.pin,0)time.sleep(.5)...
# test_ui.py
@pytest.mark.parametrize("ledpin",range(120))@pytest.parallelize_and_random_orderdeftest_led_blinking_forwards_to_gpio(ledpin):gpio=MagicMock()# resource is mocked
led=Led(gpio,pin=ledpin)led.blink(times=5)assertgpio.pin(ledpin,0).was_called(5)assertgpio.pin(ledpin,1).was_called(5)
# blinker.py: the Controlling Module
board=PI()# resource is controlled here
leds=[Led(gpio=board.gpio,pin=i)foriinrange(10)]buttons=[Button(gpio=board.gpio,pin=i)foriinrange(10,20)]whilenotbuttons[5].down():leds[2].blink()
This design allows scaling, testing, mutating, whatnot without touching the consumer. It stays clear from global limitation of the number of resources, but still results in no accidental overallocation. That is achieved by separating the allocation from the retrieval.
# distributed_blinker.py
# there are many boards, controlled here
warning_board=RemotePI("192.168.1.95")display_board=RemotePI("192.168.1.211")warning_led=Led(warning_board.gpio,1)good_led=Led(display_board.gpio,1)stop_check=Button(display_board.gpio,2)whilestop_check.down():good_led.blink()warning_led.blink()
Dang, whenever I discuss something with you, I end up writing an article :).
Organiser of the Edinburgh Language Exchange and The Edinburgh Open Tech Scene |
Full Snack Developer 🥪, Ramen guzzler 🍜, quiche murderer 🥧. A friendly cat.
Ah... an item that needs a shared resource receives the reference to said resource on instantiation , and does not tryo to go looking for it... I think I get it....
We have a situation where due to our testing framework itself (and an old inherited testing fixture), our instance does not have control of the instantiation of the TestCase (nor do we specify the main() function).... and that's why I was not thinking in that direction.
But this actually does make more sense to me... probably.
Dang, whenever I discuss something with you, I end up writing an article :).
Glad to be of service 🤣 And thank you, you have LED me to enlightenment ( .... 🦗.... )
For further actions, you may consider blocking this person and/or reporting abuse
We're a place where coders share, stay up-to-date and grow their careers.
...
Not exactly. This moves the singleton implementation logic to the module, but doesn't change its general principle. Better than the class, but
not flexible, and hardly testable (think test case interdependencies). It does prove that no Singletons are needed in Python, even if you want to reify the pattern.
What I meant was inverting control: the consumer does not request the resource at run time, but is injected with the resource by its controlling module at construction time. The life of the resource is controlled by the controlling module:
This design allows scaling, testing, mutating, whatnot without touching the consumer. It stays clear from global limitation of the number of resources, but still results in no accidental overallocation. That is achieved by separating the allocation from the retrieval.
Dang, whenever I discuss something with you, I end up writing an article :).
Ah... an item that needs a shared resource receives the reference to said resource on instantiation , and does not tryo to go looking for it... I think I get it....
We have a situation where due to our testing framework itself (and an old inherited testing fixture), our instance does not have control of the instantiation of the
TestCase
(nor do we specify themain()
function).... and that's why I was not thinking in that direction.But this actually does make more sense to me... probably.
Glad to be of service 🤣 And thank you, you have LED me to enlightenment ( .... 🦗.... )