The answer is "yes, but…"
The best way to understand is to actually try it:
>>> class RLCN:
... static_var = 5
... def method1(self):
... RLCN.static_var += 1
... def method2(self):
... self.static_var += 1
>>> rlcn = RLCN()
>>> RLCN.static_var, rlcn.static_var
(5, 5)
>>> rlcn.static_var
5
>>> rlcn.method1()
>>> RLCN.static_var, rlcn.static_var
(6, 6)
>>> rlcn.method2()
>>> RLCN.static_var, rlcn.static_var
(6, 7)
What happened?
Well, accessing a class attribute through self works just fine. If there is no instance attribute of the same name, you get the class attribute.
But assigning to it will hide the class attribute with a new instance attribute of the same name. Which is probably not what you wanted.
Note that this means you can use class attributes as "default values" or "initial values" for instance attributes. But I'm not sure it's very Pythonic to do so; what's actually happening, and what a novice (especially someone coming from, e.g., C++11 or Java) thinks is happening, are very different.
(Things get slightly more complicated when you deal with descriptors, like methods or @propertys, but let's ignore that; in the simple case that you're discussing, it's not relevant.)
I'd rather do something like class(self).static_var += 1, because long names are unreadable.
You can, you just need to spell it right: type is the function that returns the type of any object. So:
type(self).static_var += 1
This has the added advantage of being dynamic (e.g., when you have multiple inheritance and don't know which side a @property comes from, you probably don't want to explicitly list a class name, for basically the same reason you want to use super() instead of explicitly calling a base class method).
This has the disadvantage of not working on old-style classes in Python 2.x, but then you shouldn't be using those anyway. Especially in classes that have a need for class attributes, because those are exactly the types you're often going to later want to add @classmethods, @propertys, etc. to, and none of that works with old-style classes (along with many other things). If you really need to handle old-style and new-style classes transparently for some reason, self.__class__ is works with old-style classes. I'm not sure it's guaranteed to work with new-style classes; the docs say that the return value of type(object) is "generally the same object as returned by object.__class__", but doesn't say under what conditions that "generally" is untrue. It's also documented as a special attribute "added by the implementation" for "several object types" in 3.x. In practice, I don't know of any cases where they're different in 3.x, and in 2.x, the most prominent case where they're different is old-style classes.
The answer is "yes, but…"
The best way to understand is to actually try it:
>>> class RLCN:
... static_var = 5
... def method1(self):
... RLCN.static_var += 1
... def method2(self):
... self.static_var += 1
>>> rlcn = RLCN()
>>> RLCN.static_var, rlcn.static_var
(5, 5)
>>> rlcn.static_var
5
>>> rlcn.method1()
>>> RLCN.static_var, rlcn.static_var
(6, 6)
>>> rlcn.method2()
>>> RLCN.static_var, rlcn.static_var
(6, 7)
What happened?
Well, accessing a class attribute through self works just fine. If there is no instance attribute of the same name, you get the class attribute.
But assigning to it will hide the class attribute with a new instance attribute of the same name. Which is probably not what you wanted.
Note that this means you can use class attributes as "default values" or "initial values" for instance attributes. But I'm not sure it's very Pythonic to do so; what's actually happening, and what a novice (especially someone coming from, e.g., C++11 or Java) thinks is happening, are very different.
(Things get slightly more complicated when you deal with descriptors, like methods or @propertys, but let's ignore that; in the simple case that you're discussing, it's not relevant.)
I'd rather do something like class(self).static_var += 1, because long names are unreadable.
You can, you just need to spell it right: type is the function that returns the type of any object. So:
type(self).static_var += 1
This has the added advantage of being dynamic (e.g., when you have multiple inheritance and don't know which side a @property comes from, you probably don't want to explicitly list a class name, for basically the same reason you want to use super() instead of explicitly calling a base class method).
This has the disadvantage of not working on old-style classes in Python 2.x, but then you shouldn't be using those anyway. Especially in classes that have a need for class attributes, because those are exactly the types you're often going to later want to add @classmethods, @propertys, etc. to, and none of that works with old-style classes (along with many other things). If you really need to handle old-style and new-style classes transparently for some reason, self.__class__ is works with old-style classes. I'm not sure it's guaranteed to work with new-style classes; the docs say that the return value of type(object) is "generally the same object as returned by object.__class__", but doesn't say under what conditions that "generally" is untrue. It's also documented as a special attribute "added by the implementation" for "several object types" in 3.x. In practice, I don't know of any cases where they're different in 3.x, and in 2.x, the most prominent case where they're different is old-style classes.
Use self.__class__.classAttr. This should work for both old & new style classes.
Videos
I'm currently working on a linguistic project involving numerous data, classes, and thus instance variables (or properties) which I expect to grow in number after some significant progress.
So far, I've known three ways on getting and setting instance variables in all my classes:
Directly getting/setting an instance variable using the instance keyword self, e.g. self.my_variable
Using getter and setter methods, e.g. set_my_variable() and get_my_variable()
Using the @property decorator for methods that act as the instance variable themselves
I've been using the third way to define my classes by enclosing the instances' attributes in underscored variables (e.g. self._foo) and later on declaring property methods to gain access to those variables.
I admit that it may get too messy later on when my package expands, and having little confidence with my code, I just want to know which of the three do you usually use and do you have any recommendations as to which should be preferred?
in main.py I have a class called "Game", and a variable containing an instance of that class, called "game". In another file called SpriteClass.py I have a class that contains a function where I need to access the variables from the Game instance. I tried importing main.py, but whenever I do that, and write main.game.variableName I get a warning from Pycharm saying Cannot find reference 'game' in 'main.py'
Since this function in SpriteClass.py is going to be run in the Game class in main.py I also tried making an argument where I could input the variable containing the Game class reference, but even in the Game class it couldn't find the reference to the "game" variable.
Is there something I am doing wrong? How am I supposed to get access to the class instance variable from main.py into SpriteClass.py?
Here are the relevant files:
https://pastebin.com/Dr6kYZhH
https://pastebin.com/GQckCNDf
Is this what you want to achieve?
class a:
var = 0
def foo(self):
print(self.var)
b = a()
b.foo() # "print(b.var)" also works
Above code gives the following result:
0
Python acts in a bit of a tricky way with class variables imo. Taking this snippet of code as example :
class a:
var = 0
def foo(self):
self.my_name = [k for k,v in globals().items() if v is self][0]
print(f'----------{self.my_name}.var adress:', id(a.var))
print(f'self.var in {self.my_name} instance:', id(self.var))
def change(self):
print(f'changing self.var value to 1 in {self.my_name} instance')
self.var = 1
b = a()
c = a()
b.foo()
c.foo()
c.change()
b.foo()
c.foo()
which outputs
----------b.var adress: 140434476089552
self.var in b instance: 140434476089552
----------c.var adress: 140434476089552
self.var in c instance: 140434476089552
changing self.var value to 1 in c instance
----------b.var adress: 140434476089552
self.var in b instance: 140434476089552
----------c.var adress: 140434476089552
self.var in c instance: 140434476089584
You can see that some write operation (self.var = 1) in the c context did create a new variable (an instance variable) for c. This is something you really have to be aware of, otherwise you won't work with class variables but only uncorrelated instance variables.
Instead, you should always use a.var. This is also why method accessing class variables only should not have self as a parameter, to avoid this confusion.
The answer, in a few words
In your example, itsProblem is a local variable.
Your must use self to set and get instance variables. You can set it in the __init__ method. Then your code would be:
class Example(object):
def __init__(self):
self.itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
But if you want a true class variable, then use the class name directly:
class Example(object):
itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
print (Example.itsProblem)
But be careful with this one, as theExample.itsProblem is automatically set to be equal to Example.itsProblem, but is not the same variable at all and can be changed independently.
Some explanations
In Python, variables can be created dynamically. Therefore, you can do the following:
class Example(object):
pass
Example.itsProblem = "problem"
e = Example()
e.itsSecondProblem = "problem"
print Example.itsProblem == e.itsSecondProblem
prints
True
Therefore, that's exactly what you do with the previous examples.
Indeed, in Python we use self as this, but it's a bit more than that. self is the the first argument to any object method because the first argument is always the object reference. This is automatic, whether you call it self or not.
Which means you can do:
class Example(object):
def __init__(self):
self.itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
or:
class Example(object):
def __init__(my_super_self):
my_super_self.itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
It's exactly the same. The first argument of ANY object method is the current object, we only call it self as a convention. And you add just a variable to this object, the same way you would do it from outside.
Now, about the class variables.
When you do:
class Example(object):
itsProblem = "problem"
theExample = Example()
print(theExample.itsProblem)
You'll notice we first set a class variable, then we access an object (instance) variable. We never set this object variable but it works, how is that possible?
Well, Python tries to get first the object variable, but if it can't find it, will give you the class variable. Warning: the class variable is shared among instances, and the object variable is not.
As a conclusion, never use class variables to set default values to object variables. Use __init__ for that.
Eventually, you will learn that Python classes are instances and therefore objects themselves, which gives new insight to understanding the above. Come back and read this again later, once you realize that.
You are declaring a local variable, not a class variable. To set an instance variable (attribute), use
class Example(object):
def the_example(self):
self.itsProblem = "problem" # <-- remember the 'self.'
theExample = Example()
theExample.the_example()
print(theExample.itsProblem)
To set a class variable (a.k.a. static member), use
class Example(object):
def the_example(self):
Example.itsProblem = "problem"
# or, type(self).itsProblem = "problem"
# depending what you want to do when the class is derived.
So in Java I think it's pretty bad practice to make a class then access the variables of an instance of that class by doing myObj.name. Instead you would make a getter, and then call myObj.getName(). What about in Python? Are getters preferred? Or should you just get the instance variables? What's "proper"?
There are two ways to access it
first: self.__class__.PAD_token
second: self.PAD_token
If you just need to access class variables, the first one is recommended
You are trying access variable that you assigned in your class. Here PAD_token can be called as class variable.
you can access it by class name Vocabulary.PAD_token or by self self.PAD_token.
In your case dictionary will place its value to the key i.e.
{0:"PAD"} #ignoring other keys
because you have assigned that to 0 in initialization.
I want to take the username variable from another class method and call it in another class.
A summarised version of my code for a online banking system with login:
https://pastebin.com/gBcEGQFP
How do I go about doing this? Any help is greatly appreciated!