Class Variables Is Shared Across All Instances in Python

class variables is shared across all instances in python?

var should definitely not be shared as long as you access it by instance.var or self.var. With the list however, what your statement does is when the class gets evaluated, one list instance is created and bound to the class dict, hence all instances will have the same list. Whenever you set instance.list = somethingelse resp. self.list = somethingelse, it should get an instance level value.

Example time:

>>> class A():
... var = 0
... list = []
...
>>> a = A()
>>> b = A()
>>> a.var
0
>>> a.list
[]
>>> b.var
0
>>> b.list
[]
>>> a.var = 1
>>> b.var
0
>>> a.list.append('hello')
>>> b.list
['hello']
>>> b.list = ['newlist']
>>> a.list
['hello']
>>> b.list
['newlist']

Share variable between instances of the same class in python

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

Python class variable is shared with all instances

Using list_=[] in a method argument is a bad Python idiom, for the reason you've discovered. Use the following instead:

class ListClass:
def __init__(self, list_=None):
if list_ is None:
list_ = []
self.list_ = list_

def add_item(self, item):
self.list_.append(item)

list_ is set to [] when __init__ is initially parsed. A list, however, is mutable, and not copied upon assignment. So when the __init__ method is run, each time, it uses the same initial list. With the above replacement, list_ is assigned to a new list every time __init__ is run, and the problem is circumvented. The same holds for a dict as a default for function argument value. It doesn't matter if the list or dict are empty or contain values (__init__(self, list_=[5]) would have had the same problem: don't use a mutable variable in a function argument as a default value.

See the warning in the tutorial section of default function arguments.

Other more Pythonic idioms are using CamelCase for class names, and using somelist.append(item) instead of somelist += [item].

Python - Sharing variables between different instances of different classes

You can't have references to variables in Python. A variable is just a name, in some namespace (usually the __dict__ of a module, class, or instance object, or the special local namespace inside a function-call frame), for a value.

You can have references to values, but of course numbers are immutable values, so you can't change the number 1 into the number 2.

So, what you can do is create some kind of mutable value that holds the number, and share references to that.


One obvious possibility is to just give each Specific instance a reference to the General instance that created it:

class General():
def __init__(self):
self._shared_variable = 0
self._specific1 = Specific(self)
self._specific2 = Specific(self)

class Specific():
def __init__(self, shared_general):
self._shared_general = shared_general
def modify_shared_variable(self):
self._shared_general._shared_variable +=1

Another possibility is to store a single-element list:

class General():
def __init__(self):
self._shared_variable = [0]
self._specific1 = Specific(self._shared_variable)
self._specific2 = Specific(self._shared_variable)

class Specific():
def __init__(self, shared):
self._shared = shared
def modify_shared_variable(self):
self._shared[0] += 1

(This is really the same thing you're doing in C++, but without the syntactic sugar of arrays and pointers being nearly the same thing…)


Or you can create a simple MutableInteger class that holds an int, proxies non-mutating methods to it, adds a set method to replace it, and handles += and other mutating methods by calling set and returning self, instead of returning a new value.

Member variable getting shared across multiple objects- python

The dictionary is updated because of the way you used the default value in the __init__ constructor. In the first case, that empty dict is a single object; it is not a unique constructor for each new object. It gets evaluated when the class is defined, and the same dict object sits there for each new object instantiated. Very simply, the line

def __init__(self, x, y={}):

is executed once, when the function is defined, during the class definition.

In your second case, the initialization self.y = {} is in the body of the function, and so gets executed each time you instantiate a new object. You can see the longer explanation in this canonical posting on the topic.

Python class variable accessed by multiple instances

Your code fails because you tried to access a global variable idx without properly declaring it. You need to access your class variable.

class Test(object):
idx = 0
def add(self):
Test.idx += 1

obj = Test()
obj.add()
print(Test.idx)
obj = Test()
obj.add()
print(Test.idx)

Output:

1
2

Class variable is not shared with class instances

If you create an instance of A and try and read the b attribute it will return the class variable because no instance variable exists:

>>> class A():
... b='class'
>>> z = A()
>>> z.b
'class'

When you assign a value to z.b you are creating an instance variable with the name b which shadows the class variable:

>>> class A():
... b='class'
>>> z = A()
>>> z.b = 'instance'
>>> z.b
'instance'

If you want to access the class variable regardless of whether an instance variable with the same name exists, you can use __class__:

>>> class A():
... b='class'
>>> z = A()
>>> z.b = 'instance'
>>> z.b
'instance'
>>> z.__class__.b
'class'

Class (static) variables and methods

Variables declared inside the class definition, but not inside a method are class or static variables:

>>> class MyClass:
... i = 3
...
>>> MyClass.i
3

As @millerdev points out, this creates a class-level i variable, but this is distinct from any instance-level i variable, so you could have

>>> m = MyClass()
>>> m.i = 4
>>> MyClass.i, m.i
>>> (3, 4)

This is different from C++ and Java, but not so different from C#, where a static member can't be accessed using a reference to an instance.

See what the Python tutorial has to say on the subject of classes and class objects.

@Steve Johnson has already answered regarding static methods, also documented under "Built-in Functions" in the Python Library Reference.

class C:
@staticmethod
def f(arg1, arg2, ...): ...

@beidy recommends classmethods over staticmethod, as the method then receives the class type as the first argument.

How to avoid having class data shared among instances?

You want this:

class a:
def __init__(self):
self.list = []

Declaring the variables inside the class declaration makes them "class" members and not instance members. Declaring them inside the __init__ method makes sure that a new instance of the members is created alongside every new instance of the object, which is the behavior you're looking for.



Related Topics



Leave a reply



Submit