J Agustin Barrachina
J Agustin Barrachina

Reputation: 4100

Share variable between instances of the same class in python

I have a class that I need:

  1. First instance MUST receive a parameter.
  2. All the following instances have this parameter be optional.

If it is not passed then I will use the parameter of the previous object init.

For that, I need to share a variable between the objects (all objects belong to classes with the same parent).

For example:

class MyClass:
    shared_variable = None

    def __init__(self, paremeter_optional=None):
        if paremeter_optional is None:      # Parameter optional not given
            if self.shared_variable is None:
                print("Error! First intance must have the parameter")
                sys.exit(-1)
            else:
                paremeter_optional = self.shared_variable       # Use last parameter

        self.shared_variable = paremeter_optional        # Save it for next object

objA = MyClass(3)
objB = MyClass()  

Because the shared_variable is not consistent/shared across inits, when running the above code I get the error:

Error! First intance must have the parameter

(After the second init of objB)

Of course, I could use a global variable but I want to avoid it if possible and use some best practices for this.

Upvotes: 3

Views: 3815

Answers (2)

chepner
chepner

Reputation: 532303

Update: Having misunderstood the original problem, I would still recommend being explicit, rather than having the class track information better tracked outside the class.

class MyClass:
    def __init__(self, parameter):
        ...

objA = MyClass(3)
objB = MyClass(4)
objC = MyClass(5)
objD = MyClass(5)  # Be explicit; don't "remember" what was used for objC

If objC and objD are "related" enough that objD can rely on the initialization of objC, and you want to be DRY, use something like

objC, objD = [MyClass(5) for _ in range(2)]

Original answer:

I wouldn't make this something you set from an instance at all; it's a class attribute, and so should be set at the class level only.

class MyClass:
    shared_variable = None

    def __init__(self):
        if self.shared_variable is None:
            raise RuntimeError("shared_variable must be set before instantiating")

        ...


MyClass.shared_variable = 3
objA = MyClass()
objB = MyClass()  

Upvotes: 2

blhsing
blhsing

Reputation: 107095

Assigning a value to self.shared_variable makes self.shared_variable an instance attribute so that the value is not shared among instances.

You can instead assign the value explicitly to the class attribute by referencing the attribute of the instance's class object instead.

Change:

self.shared_variable = paremeter_optional

to:

self.__class__.shared_variable = paremeter_optional

Upvotes: 3

Related Questions