-1

I have several child classes in my code, and there is a specific attribute for which I don't want any child classes to have the same value. Let's call this attribute command_name

I tried to implement that using init_subclasses :

class Parent:
    list_of_unique_values_command_name = list()
    def __init_subclass__(cls, **kwargs):
        super().__init_subclass__(**kwargs)
        if hasattr(cls, "command_name"):
            if cls.command_name in Parent.list_of_unique_values_command_name:
                raise ValueError("cant have the same attribute value twice")
            Parent.list_of_unique_values_command_name.append(cls.command_name)

Child1

class ChildOne(Parent):
    command_name = "blabla"

    def __init__():
        print("hello1")

Child2

class ChildTwo(Parent):
    command_name = "blabla"

    def __init__():
        print("hello2")

This code works as expected when all classes are parsed by the Python interpreter. However, let's say the child classes are on different modules, and I run a command which only use one of them, Python won't detect that two child classes have the command_name attribute with the same value.

Is there any solution to fix this?

Edit1: I'm not searching for a solution such as a Singleton. The goal is that even if two child classes run in two different processes, they still can't have the same command_name attribute. (And it must be stateless)

nolwww
  • 1,355
  • 1
  • 15
  • 33
  • 1
    Use UUIDs for the command names. That's the only way to guarantee they can't be the same if none of the subclasses can see each other or any shared state. – Samwise Apr 27 '22 at 15:42
  • "However, let's say the child classes are on different modules, and I run a command which only use one of them, Python won't detect that two child classes have the command_name attribute with the same value." That is absolutely not true. You seem to mean *on two different processes*. Which is an *entirely different circumstance*. Is that correct? – juanpa.arrivillaga May 24 '23 at 20:13

2 Answers2

1

If you have different modules on the same process you are good to go as you are: every class in the same process which inherits from your Parent class will share the same registry in the class, the list_of_unique_values_command_name attribute.

(The only remark is that it can be a set instead of a list, but there is little practical difference).

Now, if you have serveral processes as you mention en passant, each running a different set of derived classes, and you want a single registry, that is more complex: You need to have a resource that is shared across all processes that would allow you to check for the uniqueness of the attributes you want.

I'd suggest using redis for that - if you can make all your processes connect to a single redis instance, it is trivial to keep the list of used names in the redis DB, instead of in a particular running process, as a class attribute. https://redis.io/docs/clients/python/

jsbueno
  • 99,910
  • 10
  • 151
  • 209
-3

Use a singleton class to create the Parent class. That should make it so that only one instance of Parent exists and that can store a global state.

Other than that, you could use something like SQLite to store information if that is simpler for you so that you can create a one-to-one mapping for classes and their names.

Niteya Shah
  • 1,809
  • 1
  • 17
  • 30