Reputation: 312
So, i created Some class
class Some:
@classmethod
def __init__(cls, somevar):
cls.somevar = somevar
@classmethod
def read(cls):
return cls.somevar
Now I tried to set variable outside and read it from class:
instance = Some([1, 2, 3])
instance.somevar = [4, 5, 6]
print(instance.read())
>>>> [1, 2, 3]
But calling same named variable outside class give me expected output instead,
print(instance.somevar)
>>>> [4, 5, 6]
What is my misunderstanding about the OOP?
EDIT
My goal is to create multiple instances of Some
that will have their own values.
Upvotes: 2
Views: 80
Reputation: 9977
In fact, you misunderstood what a class variable is. When you're using
instance.somevar = [4, 5, 6]
it doesn't mutate the value that you think. Instead, what you'd need to do is change the actual class variable like so,
instance = Some([1, 2, 3])
instance.somevar = [4, 5, 6]
print(instance.read())
instance2 = Some([4, 5, 6])
print(instance.read())
>>>>
[1, 2, 3]
[4, 5, 6]
Indeed, don't forget that by using the @classmethod
decorator, cls
is actually the class itself. Therefore, in your case, cls.somevar
will be shared across all classes. Also, since you decorated your __init__
, you'll be changing the value of that variable every time you will instantiate the class as shown empirically in my above example.
Note that this is probably not the implementation you are looking for. You probably want to be using self
like this instead,
class Some:
def __init__(self, somevar):
self.somevar = somevar
def read(self):
return self.somevar
instance = Some([1, 2, 3])
print(instance.read())
instance.somevar = [4, 5, 6]
print(instance.read())
>>>>
[1, 2, 3]
[4, 5, 6]
Upvotes: 5
Reputation: 189467
You probably need to better understand the difference between a class and an instance. Perhaps the following code will help.
class Some():
classvar = 123
def __init__ (self, value):
self.instvar = value
def read_instvar (self):
return self.instvar
def read_classvar (self):
return self.__class__.classvar
@classmethod
def update_classvar(cls, value):
cls.classvar = value
So now we can create several objects and see how they interact.
>>> first = Some(12)
>>> second = Some(34)
>>> second.update_classvar(456)
>>> first.read_classvar()
456
>>> first.read_instvar()
12
>>> second.read_instvar()
34
>>> second.read_classvar()
456
Observe how instvar
is the attribute of each instance; so first
has a value which is distinct from that of second
. Notice however how classvar
is shared between these instances, because they belong to the same class, and the class variable is a property of that class, not of any one instance. Concretely, even though we changed the class variable via second
, the change is also visible in first
.
Upvotes: 1
Reputation: 136
It is more like a scope problem.
instance = Some([1, 2, 3])
instance.somevar = [4, 5, 6]
print(instance.read())
>> [1, 2, 3]
Some.somevar = [4, 5, 6]
print(instance.read())
>> [4, 5, 6]
All is based on the fact that in Python, 2 variables with same name can be used in a instance scope and in a class scope and have different values.
Upvotes: 0
Reputation: 808
Use print(instance.somevar)
to get the somevar value, but you change it inside your function, not globally
Upvotes: 1