This question already has answers here:
python subclass access to class variable of parent
(2 answers)
Closed 6 years ago.
In Python, when defining a class it's possible to use previously defined attributes in new attributes definition without any further reference.
class Parent(object):
a_value = 'a'
another_value = 'b'
all_values = (a_value, another_value)
Is it possible to do the same in a derived class but still accessing some of these parent attributes?
I tried doing something like this:
class Child(Parent):
a_child_value = 'c'
all_values = (a_value, another_value, a_child_value)
But it seems that it doesn't take into account the Parent inheritance and gives me the following error:
NameError: name 'a_value' is not defined
So, is there any way to indicate that the a_value and another_value should be from the parent class instead of the current context?
In my case in particular the values are not strings but rather pre-compiled regular expressions, so I would like to avoid having to create them inside the __init__ method every time a new instance is created.
like this.
class Child(Parent):
a_child_value = 'c'
all_values = (Parent.a_value, Parent.another_value, a_child_value)
You need to do Parent.a_value in order to get the value you are after. a_child is a static attribute and therefore attached to the class itself and not a local variable.
class Child(Parent):
a_child_value = 'c'
all_values = (Parent.a_value, Parent.another_value, a_child_value)
If it is derived from something, you HAVE to type what it is derived from.
Related
This question already has answers here:
Class (static) variables and methods
(27 answers)
Closed 6 years ago.
I read somewhere that "if python can't find instance variable it will try to return value of the class variable having the same name"
eg
class Sample:
pi = 10
Now
x1 = Sample()
x2 = Sample()
x1.pi # returns 10
x2.pi # returns 10
x1.pi = 20 # change the value of class variable
x1.pi # return 20 (OK)
x2.pi # still returns 10 :(
Sample.pi # returns 10 :(
What is happening??
As soon as you assign to a name on an instance, it gains an instance attribute that shadows the class attribute.
The only way you can assign to the class attribute is to assign to an attribute of the class, not an attribute of the instance, e.g. if you have an instance, you need to do:
x1.__class__.pi = 20
# If you're on Py3, or on Py2 and x1 is an instance of a new-style class,
# using type(x1) is slightly "nicer" than manually accessing dunder special
# variables, but unfortunately, it doesn't work on old-style class instances
# For new-style class instances though, the following is equivalent:
type(x1).pi = 20
if you want all instances of the same type as x1 to show the change. This gets the class itself from __class__ (or via type function), then assigns to it.
If you accidentally created an instance attribute and want to expose the class attribute again, you can do:
del x1.pi
which will succeed if an instance attribute named pi exists, and raise AttributeError if it does not (it will not delete the class attribute if it exists, you'd need to do del x1.__class__.pi/del type(x1).pi to do that).
This question already has answers here:
How do I call a parent class's method from a child class in Python?
(16 answers)
Closed 6 years ago.
I have been unable to find any questions on this or maybe I am using the wrong nomenclature in my search. If I have something like:
class testone(object):
def __init__(self):
self.attone = None
self.atttwo = None
self.attthree = None
class testtwo(testone):
def __init__(self):
self.attfour = None
And I do:
a = test()
print dir(a)
b = testtwo()
print dir(b)
One can see that a will have all of it's attributes defined as None but b will only have attfour defined even though it inherited class testone. I understand this, but is it possible to make b have all of the attributes inherited from a implicitly defined as well at instantiation ?
I ask b/c I have classes that have tens of attributes that are inheriting from classes with hundreds of attributes and I need every attribute to be defined even if it is of type None so that I don't have to worry about checking if the attribute exists before mapping it from my object to a database table. I am trying not to write as much code. If there is a way to do this then I save well over a thousand lines of code in my class definitions or I could just verify if each attribute exists before mapping the object to my table but that's a lot of code as well as I have a couple thousand attributes to check.
Yes, but since you have overridden __init__ in the derived class, you will have to explicitly init the next class in the mro (a parent or sibling class).
class testone(object):
def __init__(self):
self.attone = None
self.atttwo = None
self.attthree = None
class testtwo(testone):
def __init__(self):
self.attfour = None
super(testtwo, self).__init__() # on python3 just use super()
For more details on inheritance, read the docs on super.
Note: I assumed you have meant for testtwo to inherit testone in your question, and have made that correction.
Since you overrode testone.__init__ you will have to call the super() function in testtwo. Another thing you can do is take the __init__ variables
class testone(object):
attone = None
atttwo = None
attthree = None
class testtwo(testone):
attfour = None
This question already has answers here:
Python class attribute referencing
(2 answers)
Closed 7 years ago.
Is it possible to access self.bin outside the class?
class kon():
def __init__(self):
pass
def add(self):
con=7
self.bin=100
h=kon()
bin=h.bin
In one topic advised to use self. before variables but it did not work.
Maybe such variables must be in __init__ method.
You have to read docs. It will be very useful for you.
The instantiation operation (“calling” a class object) creates an empty object. Many classes like to create objects with instances customized to a specific initial state. Therefore a class may define a special method named init(), like this:
def __init__(self):
self.bin = 0
When a class defines an init() method, class instantiation automatically invokes init() for the newly-created class instance.
After this you can use this property in you object, to read or assign value.
Also, there is a difference between initialize properties in the class. From the docs:
class Dog:
kind = 'canine' # class variable shared by all instances
def __init__(self, name):
self.name = name # instance variable unique to each instance
This question already has answers here:
Nested Python class needs to access variable in enclosing class
(6 answers)
Closed 8 years ago.
I'm trying to assign a variable in my inner class with the variable on the outer class.
class OUTER(QtGui.QWidget):
def __init__(self):
super (OUTER, self).__init__()
self.initUI()
def number (self):
self.out = 50
...
class INNER(QtGui.QLCDNumber)
in = OUTER.out #error: NameError: name 'OUTER' is not defined
#pyqtSlot()
def some_func(self):
self.display(self.in)
I'm getting an error
NameError: name 'OUTER' is not defined.
Is there any way to fix this?
You can't do this.
OUTER is not defined until the entire outer class declaration is finished. Class bodies are executable code; they are executed at definition time. When the body is defined, it is allocated to the name, but until then the name does not exist.
That is one of the reasons why nesting classes is rarely a good idea in Python. The inner class does not get any special access to the outer class, so there isn't really any reason to nest them at all.
Plus, I've just noticed that you are trying to refer to an instance variable via a class. That can't ever work. OUTER.out does not exist, only instances of OUTER have an out attribute. (What would the value of OUTER.out even be?)
This question already has answers here:
How to avoid having class data shared among instances?
(7 answers)
Closed 9 years ago.
Look at the code below:
class Node:
feature = list()
label = list()
def __init__(self, f, l):
self.feature.append(f)
self.label.append(l)
I create two instances of this class:
n1 = Node(1,2)
print n1.feature
n2 = Node(3,4)
print n2.feature
My desired output is:
1
2
But the real output is:
1
1 2
What is the problem? How can I fix it?
variables defined in class scope are class variables, and are share among all class instances (they are stored on the class object itself, not on the instances).
Just initialize the variables inside the init function.
class Node:
def __init__(self, f, l):
self.feature = [f]
self.label = [l]
The issue is that you're trying to "declare" the member data for the class instances in the class block. That's not how Python works.
Everything defined in the class block (including feature, label, and __init__) becomes an attribute of the object that represents the class itself, not the instances of the class. Trying to access an attribute that doesn't exist in an instance will fall back to the class, which is how method lookup works.
There is no way to create a attribute on an instance until it exists and you have a reference to it. The purpose of the __init__method is to give you a place to do that. So initial values for an instance's member data should be set up in __init__; trying to declare these initial values in the class block actually does something else.