Python Forum

Full Version: Pythonic way to handle/spread alerts class in multiple modules
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Pages: 1 2
I have a class to handle alerts that, at the end of the process, will be sent in an email. This alerts are list that should be updated during the process execution.

The point is that the process uses different modules (classes) in different files so...

My question is: what is the pythonic way of handling this alerts class?
  • Declare it at the beginnig of the process and pass it as argument to the different modules handlers?
  • Maybe create it as Singleton?
  • Any other idea is obviously welcome!

I think this python pattern (Borg) could help me...

https://github.com/faif/python-patterns/...al/borg.py

class Borg:
    __shared_state = {}

    def __init__(self):
        self.__dict__ = self.__shared_state
        self.state = 'Init'

    def __str__(self):
        return self.state


class MyBorg(Borg):

    def __init__(self):
        Borg.__init__(self)
        self.alert_one = []
        self.alert_two = []
        ...
But when I import and instantiate the class, lists are empty.

The point is that I don't know if using Singleton in this kind of situation is good idea or not...

Thank you in advance!
(Feb-05-2020, 01:15 PM)psolar Wrote: [ -> ]But when I import and instantiate the class, lists are empty.
It does work as intended for me.
class Borg:
    shared_state = {}

    def __init__(self):
        self.__dict__ = self.shared_state
        self.state = 'Init'
usage:
>>> from test11 import Borg
>>> borg1 = Borg()
>>> borg2 = Borg()
>>> borg1.state
'Init'
>>> borg2.state
'Init'
>>> borg1.state = 'test'
>>> borg1.state
'test'
>>> borg2.state
'test'
If done this way i would definitely make the variable name obvious that it is shared to avoid thinking it is an instance attribute independent from other instances.

I usually call Borg.shared_state directly when changing or referring to any class attribute. Im not sure which is more pythonic to be honest.
Hello again,

I tried, but if I use the Borg in diferent modules, it does not keep the state. It only does when it is declared Singleton instead Borg.

My question is... is pythonic to use this approach (use Singleton for this purpose)?

Thank you all!
You can use @property to define attributes that cannot be written. For example
class MyBorg:
    __shared = {
        '_alert_one': [],
        '_alert_two': [],
    }
    
    def __init__(self):
        self.__dict__ = self.__shared

    @property
    def alert_one(self):
        return self._alert_one

    @property
    def alert_two(self):
        return self._alert_two


b = MyBorg()
b.alert_one.append('spam')

c = MyBorg()
print(c.alert_one) # <--- prints ['spam']

# One cannot set the attribute
# c.alert_one = 'bar'  # raises AttributeError
Ok, thank you.

But I would like to know if the Singleton's approach is correct and pythonic or, on the contrary, it is better to create an instance of the class and pass it on as an argument to the other classes and in the other modules.

Thank you!
I would say it would depend on what you were doing on whether it was pythonic or not. In most cases i pass the object.
This works, but is this pythonic if I instantiate MyBord class in different classes? For example in class A, in class B (which is also instantiated form class A and in different module), class C, ...?

(Feb-07-2020, 09:38 AM)Gribouillis Wrote: [ -> ]You can use @property to define attributes that cannot be written. For example
class MyBorg:
    __shared = {
        '_alert_one': [],
        '_alert_two': [],
    }
    
    def __init__(self):
        self.__dict__ = self.__shared

    @property
    def alert_one(self):
        return self._alert_one

    @property
    def alert_two(self):
        return self._alert_two


b = MyBorg()
b.alert_one.append('spam')

c = MyBorg()
print(c.alert_one) # <--- prints ['spam']

# One cannot set the attribute
# c.alert_one = 'bar'  # raises AttributeError
psolar Wrote:This works, but is this pythonic if I instantiate MyBord class in different classes?
Honestly, I must confess that I never use borgs. I use singletons but usually I don't declare them as such. I simply define a class and create a single instance. There was a time where singletons and borgs were trendy but it is not very useful to declare them as such. The pythonic philosophy is not to enforce gentlemen's agreements. For example you may define a python function which first argument must be a list (otherwise the function won't work), but you often don't enforce this requirement by checking the argument's type.
(Feb-11-2020, 06:41 PM)Gribouillis Wrote: [ -> ]I use singletons but usually I don't declare them as such. I simply define a class and create a single instance
same
(Feb-12-2020, 12:07 AM)metulburr Wrote: [ -> ]
(Feb-11-2020, 06:41 PM)Gribouillis Wrote: [ -> ]I use singletons but usually I don't declare them as such. I simply define a class and create a single instance
same

OK and how do you handle it? I mean... If we have:

Core -> Handler -> Class A -> Class B | Class C | ..

And We need to use the same instance (state) in Handler, Class A, Class C and Class K... how do you handle it without declaring it Singleton and without passing it as argument in the different classes?
Pages: 1 2