How to access "myvar" from "child" in this code example:
class Parent():
def __init__(self):
self.myvar = 1
class Child(Parent):
def __init__(self):
Parent.__init__(self)
# this won't work
Parent.myvar
child = Child()
Parent is a class - blue print not an instance of it,
in OOPS to access attributes of an object it requires instance of the same,
Here self/child is instance while Parent/Child are classes...
see the answer below, may clarify your doubts.
class Parent():
def __init__(self):
self.myvar = 1
class Child(Parent):
def __init__(self):
Parent.__init__(self)
# here you can access myvar like below.
print self.myvar
child = Child()
print child.myvar
Parent does not have an attribute called myvar. Only instances of parent have that attribute. From within a method of Child, you can access that attribute with self.myvar.
Alternative to using inheritance
The current answers are coming from an inheritance perspective, but this isn't always what you want -- sometimes you might want the child to be an entirely different type of object to the parent, but that still has access to the parent attributes.
For a business analogue, think of Excel Workbooks which have Worksheet children, which themselves have Range children, and so on.
Only Child
An alternative approach (and not the only one) is to pass the parent as an argument to the child to create a property that corresponds to the parent:
class Parent(object):
def __init__(self, parent_value):
self.parent_value = parent_value
self.child = Child(self)
class Child(object):
def __init__(self, _parent):
self.parent = _parent
self.child_value = 0
new_parent = Parent(1)
print(new_parent.parent_value) # prints 1
new_child = new_parent.child
print(new_child.child_value) # prints 0
print(new_child.parent.parent_value) # prints 1
new_parent.parent_value = 100
print(new_child.parent.parent_value) # prints 100
Note that this instantiates the child at the same that that new_parent is instantiated. To access the parent's attributes, just go through the parent property.
Multiple Children
You could extend this so that you can create multiple instances of the Child class through the new_parent object. The code below is one simple way of doing this which replaces the child property with a children property and an add_child method.
class Parent(object):
def __init__(self, parent_value):
self.parent_value = parent_value
self.children = []
def add_child(self, child_value):
new_child = Child(child_value, _parent=self)
self.children.append(new_child)
return new_child # allows add_child to assign a variable
class Child(object):
def __init__(self, child_value, _parent):
self.parent = _parent
self.child_value = child_value
new_parent = Parent(1)
# add 3 Child instances with child_values 2, 4, 8
[new_parent.add_child(v) for v in [2, 4, 8]]
# add another child that utilises the return statement
extra_child = new_parent.add_child(16)
for child in new_parent.children:
print(child.child_value) # prints 2, 4, 8, 16
print(child.parent.parent_value) # prints 1
new_parent.parent_value = 32
for child in new_parent.children:
print(child.parent.parent_value) # prints 32
# prove that extra_child is new_parent.children[3]
extra_child.child_value = 64
print(new_parent.children[3].child_value) # prints 64
You need to initiate the parent class first via so-called proxy object using command "super".
So the code will be like this:
class Parent():
def __init__(self):
self.myvar = 1
class Child(Parent):
def __init__(self):
super.__init__()
child = Child()
print child.myvar
Related
I'm doing a project in Python which requires me to make a nested class. I need to get a variable from the class it is nested in but haven't been able to. I want to be able to get the self variables from Parent in the Child class but my code isn't working, is there any way I could inherit the Parent class' variables? Here is what I tried:
class Parent:
def __init__(self):
self.x = 1;
self.y = 2;
class Child:
def __init__(self):
pass;
def parent_vars(self):
att = super()["x"];
print(att);
parent = Parent();
child = parent.Child();
child.parent_vars();
In python, unlike in Java, a class serves more as a namespace than as an object. An inner class (in this case Parent.Child) is no different semantically than the same class defined as a standalone - the outer class is simply how it's accessed (and it's accessed statically, not requiring an instance - again unlike Java).
If you want a Child to take its Parent's variables, you'll need to tell the Child explicitly which object is its Parent:
class Parent:
def __init__(self):
self.x = 1
self.y = 2
class Child:
def __init__(self, parent):
self.parent = parent
def parent_vars(self):
att = self.parent.x
print(att)
par = Parent()
child = Parent.Child(par) # note how `Parent.Child`, not `par.Child()`
child.parent_vars()
# 1
In python, how can I setup the Parent class attributes in Child Class constructor.
My Parent class has 2 attributes which set in its constructor:
class Parent:
def __init__(self):
self.attribute1 = "abc"
self.attribute2 = 1
def afunction():
# something to print attributes"
print(self.attribute1 + self.attribute2)
In my child class, in the construtor, I try to override the attribute1, attribute2 by
class Child(Parent):
def __init__(self):
super.attribute1 = "def"
super.attribute2 = 3
But I get error TypeError: can't set attributes of built-in/extension type 'super'
What i want to when x = Child() x.afunction(), I should see it print "def3"
You should use the inheritance right way. Your parent class already have 2 attributes, but you are not exposing them to be parametrized to be instantiated by clients as well as subclasses. You could do this as follows:
class Parent:
def __init__(self, attribute1="abc", attribute2=1):
self.attribute1 = attribute1
self.attribute2 = attribute2
def afunction(self):
print(self.attribute1 + str(self.attribute2))
class Child(Parent):
def __init__(self, attribute1="def", attribute2=3):
super().__init__(attribute1, attribute2)
Child().afunction()
Child("test", 3).afunction()
This way you are allowing clients to provide value for your attributes, not reassign them in child. Also exposing attributes to the clients so they can pass them if they need else it uses the default value
To build up on my comment:
class Parent:
def __init__(self):
self.attribute1 = "abc"
self.attribute2 = 1
class Child(Parent):
def __init__(self):
self.attribute1 = "def"
self.attribute2 = 3
c = Child()
In this case, the child is initialize. In the initialization 2 attributes are created with the value def and 3. The attributes are never initialized with the values from the parent class.
Alternatively:
class Parent:
def __init__(self):
self.attribute1 = "abc"
self.attribute2 = 1
class Child(Parent):
def __init__(self):
super().__init__()
self.attribute1 = "def"
self.attribute2 = 3
c = Child()
This time, the attributes are first initialized during the super() call by calling the function __init__() from the parent class. And then they are overridden.
Which one you prefer depends on your application, but either way, you can create the attribute directly in the child class as they don't belong to one specifically.
Got It In Place Of Super() try Acccesing It With Parent.
And Then Print It I Definitely Say You Will Get Your Answer :'def'
Here's an example of what I'm trying to do:
class Parent():
def __init__():
self.parent_var = 'ABCD'
x = Child(self) # self would be passing this parent instance
class Child():
def __init__(<some code to pass parent>):
print(self.parent_var)
foo = Parent()
Now I know what you're thinking, why not just pass parent_var itself to the child instance? Well my actual implementation has over 20 class variables in Parent. I don't want to have to manually pass each variable to the __init__ of the Child instance that's instantiated in Parent-- is there a way to make all Parent class variables available to Child?
EDIT - SOLVED:
This is the way I found that works:
class Parent():
def __init__(self):
self.parent_var = 'ABCD' # but there are 20+ class vars in this class, not just one
x = Child(self) # pass this parent instance to child
class Child():
def __init__(self, parent):
for key, val in vars(parent).items():
setattr(self, key, val)
print(self.parent_var) # successfully prints ABCD
foo = Parent()
If you inherit from the parent class all variables will be present in child classes. Use super init in the child to make sure the parent class instantiates.
class Parent:
def __init__(self):
self.parent_var = 'ABCD'
class Child(Parent):
def __init__(self):
super().__init__()
child = Child()
print(child.parent_var)
prints:
'ABCD'
You would pass the instance of Parent like you would any value.
class Parent:
def __init__(self):
self.parent_var = 'ABCD'
x = Child(self)
class Child:
def __init__(self, obj):
print(obj.parent_var)
Found a solution and wanted to post the answer in case anyone who finds this needs it:
class Parent():
def __init__(self):
self.parent_var = "ABCD" # just an example
x = Child(self) # pass this parent instance (this object) to child
class Child():
def __init__(self, parent):
# copies variables from passed-in object to this object
for key, val in vars(parent).items():
setattr(self, key, val)
print(self.parent_var) # successfully prints ABCD
foo = Parent()
I have to inherit dynamic value of the Parent instance variable a.I've tried using super which gets the value which is defined in the init constructor of the Parent and also have tried passing Parent object.
Please refer the code snippet below
class Parent(object):
def __init__(self):
self.a = 1
def test(self):
self.a = 2
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
class Child1(Parent):
def __init__(self, parent):
self.a = parent.a
p = Parent()
c = Child()
c1 = Child1(p)
p.test()
print p.a #2
print c.a #1
print c1.a #1
If I use below code, the problem gets solved.However is there any way to get the instance variable value of parent which is altered after initialization.
c.test()
print c.a #2
c1.test()
print c1.a #2
Please suggest any solution for this problem.
You need to use delegation here. Instead of directly assigning self.a to the value of parent.a, you should store the parent, and then define a property that gets the value of the parent's a on request.
class Child1(object):
def __init__(self, parent):
self.parent = parent
#property
def a(self):
return self.parent.a
I'm supposed to create three classes: a parent, and child 1 and child 2.
Child 1 and 2 are supposed to inherit from the Parent class.
So I believe I've done that.
class Parent:
"""Parent Object"""
def __init__(self):
self.greeting = "Hi I'm a Parent Object!"
class ChildA(Parent):
def __init__(self):
childclass.__init__(self)
self.childgreeting = "Hi I'm a Child Object!"
class ChildB(Parent):
pass
Now I have to write a parent object and the children objects which will print out their respective strings.
That's where I'm getting confused: I already put in the strings that they are a child or parent object within their classes.
But how do I get them to print as an object?
I've started out my code like this.
class Parent(object):
class ChildA(object):
class ChildB(object):
How to get those strings to print is bugging me.
And I have a feeling that my ChildA code for the class is not correct either.
Can anyone help me?
Child 1 and 2 are supposed to inherit from the Parent class. So I believe I've done that
Yes, in the first code, you have, but not in the second code.
I have to write a parent object and child 1 and 2 objects that will print out their respective strings
Okay...
p = Parent()
child_a = ChildA()
print(p.greeting)
print(child_a.childgreeting)
However - ChildA() won't work because __init__ should look like this
class ChildA(Parent):
def __init__(self):
super().__init__() # This calls the Parent __init__
self.childgreeting = "Hi I'm a Child Object!"
Now, the above code will work.
But, I assume you want the greeting attribute to be overwritten? Otherwise you get this
print(child_a.greeting) # Hi I'm a Parent Object!
print(child_a.childgreeting) # Hi I'm a Child Object!
If that is the case, you simply change childgreeting to greeting. Then, from the first example
print(p.greeting) # Hi I'm a Parent Object!
print(child_a.greeting) # Hi I'm a Child Object!
how do I get them to print as an object?
Not entirely sure what you mean by that, but if you define __str__ to return greeting
class Parent:
"""Parent Object"""
def __init__(self):
self.greeting = "Hi I'm a Parent Object!"
def __str__(self):
return self.greeting
The example now becomes
print(p) # Hi I'm a Parent Object!
print(child_a) # Hi I'm a Child Object!
class Parent(object):
def __init__(self):
self.greeting = "Hi I am a parent"
def __str__(self):
return self.greeting
class Child(Parent):
def __init__(self):
super(Child, self).__init__()
self.greeting = "Hi I am Child"
def __str__(self):
return self.greeting
p = Parent()
print(p)
c = Child()
print(c)
This method could help you to use 'print()' statement to print out greeting for individual class. But if you want to directly get self.greeting attribute you should use
p = Parent()
print(p.greeting)
Hope I understood you since your questions seems to be not properly explained...