I'd like to store some information about a class as class (static) variables. However, I can't figure out how these things get initialized. Here is a basic, dumb example:
class A(object):
clsVar = 'a'
@classmethod
def clsMeth(cls):
print 'changing clsVar'
cls.clsVar = 'b'
A.clsMeth()
# prints 'changing clsVar'
print A.clsVar # prints 'a'
A.clsVar = 'b'
print A.clsVar # prints 'b'
Since the function got called (as the print statement worked), why didn't the class variable stay changed? Do I have to use a metaclass if I don't want to do it after the class definition completes?
[Specifically, I want clsMeth
to be a decorator and have the class variable be a list of all the functions that were so decorated. I'm guessing this isn't the right way to go about accomplishing that, so I've moved on, but I'm still curious.]
EDIT: As numerous people have pointed out, the code above won't run. I was running it in an IPython session where the call to A.clsMeth()
would refer to a previous version of A
and run. Such are the risks of using an interpreted language, I guess. I ended up going with something like this:
outsideDict = {}
def outsideDec(func):
outsideDict[func.__name__] = func
class A(object):
@outsideDec
def someMethod(self):
print 'ID %s' % id(self)
def otherMethod(self):
print 'other'
print outsideDict
one, two = A(), A()
outsideDict['someMethod'](one)
outsideDict['someMethod'](two)
Perhaps this should be another question, but when outsideDec
gets run, is there a way to tell what class it's argument is a member of? Or is there a better way of doing introspection like this in Python? I recognize I'm veering off course here so I'll accept the answer below and do more research. Thanks everyone!
Create Class VariablesA class variable is declared inside of class, but outside of any instance method or __init__() method. By convention, typically it is placed right below the class header and before the constructor method and other methods.
The __init__ method is the Python equivalent of the C++ constructor in an object-oriented approach. The __init__ function is called every time an object is created from a class. The __init__ method lets the class initialize the object's attributes and serves no other purpose. It is only used within classes.
To initialize a class member variable, put the initialization code in a static initialization block, as the following section shows. To initialize an instance member variable, put the initialization code in a constructor.
The call to A.clsMeth()
in the definition of A
will not run, as A
does not exist at that point:
>>> class A(object):
... clsVar = 'a'
... @classmethod
... def clsMeth(cls):
... print 'changing clsVar'
... cls.clsVar = 'b'
... A.clsMeth()
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 7, in A
NameError: name 'A' is not defined
The code may have seemed to work if A
had been defined previously (eg, if you were testing it out in the REPL), but the call to A.clsMeth
would have been called on the old class, which would be shadowed by the new one.
However, we can definitely put that call after the definition and get the result you want:
>>> class A(object):
... clsVar = 'a'
... @classmethod
... def clsMeth(cls):
... print 'changing clsVar'
... cls.clsVar = 'b'
...
>>> A.clsMeth()
changing clsVar
>>> A.clsVar
'b'
Of course, as fabianhrj noted, you can put it in the constructor as well, but it won't be called until you create an instance.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With