Instead of bar use self.bar or Foo.bar. Assigning to Foo.bar will create a static variable, and assigning to self.bar will create an instance variable.
Class variables
How to access class variable inside methods of that class in python? - Stack Overflow
How to reference class variables inside class method
How to refer to class methods when defining class variables in Python? - Stack Overflow
Python class method versus instance method: What’s the difference?
In Python, a class method is a method that is invoked with the class as the context. This is often called a static method in other programming languages. An instance method, on the other hand, is invoked with an instance as the context.
What is a Python namespace?
A Python namespace is a mapping from names to objects, with the property that there is zero relation between names in different namespaces. Namespaces are usually implemented as Python dictionaries, although this is abstracted away.
What happens if both instance attribute and class attribute are defined?
In that case, the instance namespace takes precedence over the class namespace. If there is an attribute with the same name in both, the instance namespace will be checked first and its value returned.
Videos
Instead of bar use self.bar or Foo.bar. Assigning to Foo.bar will create a static variable, and assigning to self.bar will create an instance variable.
Define class method:
class Foo(object):
bar = 1
@classmethod
def bah(cls):
print cls.bar
Now if bah() has to be instance method (i.e. have access to self), you can still directly access the class variable.
class Foo(object):
bar = 1
def bah(self):
print self.bar
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.
class Test:
config: Dict[str, str]
parameters: Dict[str, str]
def default(cls)
return cls(
parameters=get_params(),
config=get_config(file="ATTRIBUTE FROM PARAMETERS"
)
# I tried it like this:
class Test:
config: Dict[str, str]
parameters: Dict[str, str]
def default(cls)
return cls(
parameters=get_params(),
config=get_config(file=cls.parameters.config_file)
)
# AttributeError: type object 'Test' has no attribute 'parameters'Class body in python is an executable context, not like Java that only contains declaration. What this ultimately means is that sequence of execution is important within a class definition.
To quote the documentation:
class definition is an executable statement.
...
The class’s suite is then executed in a new execution frame (see Naming and binding), using a newly created local namespace and the original global namespace. (Usually, the suite contains mostly function definitions.) When the class’s suite finishes execution, its execution frame is discarded but its local namespace is saved. [4] A class object is then created using the inheritance list for the base classes and the saved local namespace for the attribute dictionary. The class name is bound to this class object in the original local namespace.
Some more lengthier explanations.
If you want to call a function to define a class variable, you can do it with one of these ways:
use staticmethod:
class MyClass: def _run_instance_method(): return "ran instance method" run_instance_method = staticmethod(_run_instance_method) class_var_1 = "a" class_var_2 = _run_instance_method() # or run_instance_method.__func__()or define it as a standalone function:
def run_method(): return "ran method" class MyClass: class_var_1 = "a" class_var_2 = run_method() # optional run_method = staticmethod(run_method)or access the original function with
__func__and provide a dummyclsvalue:class MyClass: @classmethod def run_class_method(cls): return "ran class method" class_var_1 = "a" class_var_2 = run_class_method.__func__(object())or set the class variables after class creation:
class MyClass: @classmethod def run_class_method(cls): return "ran class method" class_var_1 = "a" MyClass.class_var_2 = MyClass.run_class_method()
MyClass is not yet defined when its class attributes are still being defined, so at the time class_var_2 is being defined, MyClass is not yet available for reference. You can work around this by defining class_var_2 after the MyClass definition block:
class MyClass:
class_var_1 = "a"
@classmethod
def run_class_method(cls):
return "ran class method"
MyClass.class_var_2 = MyClass.run_class_method()
class Example(object):
def __init__(self, nr1, nr2):
self.a = nr1
self.b = nr2
def Add(self):
c = self.a + self.b
return c
Suppose if we create a instance x=Example().
If we try to accces c using x.c . We would get following error
AttributeError: 'Example' object has no attribute 'c'.
The difference is that on the second example you store the result of the addition to an object variable c. In the first example, c is inside a method and thus can not be a class variable since it is instantiated when the Add method is called and not when the class is defined.
Variables inside a method should be written with self just if you want to store them. A local, unimportant variable can be written inside a method just like you did on example with c.
This is because of the way Python resolves names with the .. When you write self.list the Python runtime tries to resolve the list name first by looking for it in the instance object, and if it is not found there, then in the class instance.
Let's look into it step by step
self.list.append(1)
- Is there a
listname into the objectself?- Yes: Use it! Finish.
- No: Go to 2.
- Is there a
listname into the class instance of objectself?- Yes: Use it! Finish
- No: Error!
But when you bind a name things are different:
self.list = []
- Is there a
listname into the objectself?- Yes: Overwrite it!
- No: Bind it!
So, that is always an instance variable.
Your first example creates a list into the class instance, as this is the active scope at the time (no self anywhere). But your second example creates a list explicitly in the scope of self.
More interesting would be the example:
class testClass():
list = ['foo']
def __init__(self):
self.list = []
self.list.append('thing')
x = testClass()
print x.list
print testClass.list
del x.list
print x.list
That will print:
['thing']
['foo']
['foo']
The moment you delete the instance name the class name is visible through the self reference.
Python has interesting rules about looking up names. If you really want to bend your mind, try this code:
class testClass():
l = []
def __init__(self):
self.l = ['fred']
This will give each instance a variable called l that masks the class variable l. You will still be able to get at the class variable if you do self.__class__.l.
The way I think of it is this... Whenever you do instance.variable (even for method names, they're just variables who's values happen to be functions) it looks it up in the instance's dictionary. And if it can't find it there, it tries to look it up in the instance's class' dictionary. This is only if the variable is being 'read'. If it's being assigned to, it always creates a new entry in the instance dictionary.
Neither way is necessarily correct or incorrect, they are just two different kinds of class elements:
- Elements outside the
__init__method are static elements; they belong to the class. - Elements inside the
__init__method are elements of the object (self); they don't belong to the class.
You'll see it more clearly with some code:
class MyClass:
static_elem = 123
def __init__(self):
self.object_elem = 456
c1 = MyClass()
c2 = MyClass()
# Initial values of both elements
>>> print c1.static_elem, c1.object_elem
123 456
>>> print c2.static_elem, c2.object_elem
123 456
# Nothing new so far ...
# Let's try changing the static element
MyClass.static_elem = 999
>>> print c1.static_elem, c1.object_elem
999 456
>>> print c2.static_elem, c2.object_elem
999 456
# Now, let's try changing the object element
c1.object_elem = 888
>>> print c1.static_elem, c1.object_elem
999 888
>>> print c2.static_elem, c2.object_elem
999 456
As you can see, when we changed the class element, it changed for both objects. But, when we changed the object element, the other object remained unchanged.
I think this sample explains the difference between the styles:
james@bodacious-wired:~$cat test.py
#!/usr/bin/env python
class MyClass:
element1 = "Hello"
def __init__(self):
self.element2 = "World"
obj = MyClass()
print dir(MyClass)
print "--"
print dir(obj)
print "--"
print obj.element1
print obj.element2
print MyClass.element1 + " " + MyClass.element2
james@bodacious-wired:~$./test.py
['__doc__', '__init__', '__module__', 'element1']
--
['__doc__', '__init__', '__module__', 'element1', 'element2']
--
Hello
World
Traceback (most recent call last):
File "./test.py", line 17, in <module>
print MyClass.element2
AttributeError: class MyClass has no attribute 'element2'
element1 is bound to the class, element2 is bound to an instance of the class.