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...
Related
Hi I have a simple Inheritance example in Python.
class Person:
def __init__(self,name):
self.name=name
self.name0=name[0]
self.name1=name[1]
self.lastchar=self.returnSomechar()
def returnfirstchar(self):
return self.name[0]
def returnSomechar(self):
self.p=self.name1
return self.p
class Employee(Person):
def returnfirstchar(self):
""" I dont implement at all"""
def returnSomechar(self):
a='Lawson'
b='Jack'
self.p=self.name1+a+b
#
return super(Employee,self).returnSomechar()
e=Employee('David')
e.returnSomechar()
This returned 'a'
I expected the child class self.p to get passed and result would be David Lawson Jack
Cleary In child class super() didnt use the self.p of child class rather it used self.p of base class.
can you please help where i am missing
Thanks
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 know many topics around class inheritance in Python have been addressed, but I could not find a thread that addressed this specific issue.
Edit: I'm running Python 3.5.5.
Code:
class Parent():
def __init__(self, parentParam="parent param"):
self.parentParam = parentParam
class Child(Parent):
def __init__(self, childParam = "child param"):
self.childParam = childParam
super().__init__(self)
child = Child()
print(child.childParam)
print(child.parentParam)
Output:
child param
<__main__.Child object at 0x0000017CE7C0CAC8>
Why does does child.parentParam return the child object and not the string "parent param"? I feel like it should print out the default string set for the Parent class. This appears to be the same syntax as I have been following in this tutorial.
Thanks, everyone.
Because you provide the instance of child (aka self) to the super call:
class Child(Parent):
def __init__(self, childParam = "child param"):
self.childParam = childParam
super().__init__(self) # here you override the default by supplying this instance
Use:
class Child(Parent):
def __init__(self, childParam = "child param"):
self.childParam = childParam
super().__init__()
instead and you get this output instead:
child param
parent param
Your call to super is wrong. It's not necessary to explicitly pass a self argument when using it to delegate a method call to a superclass (see the typical usage example shown in the documentation).
In Python 3, calls to super() with no arguments are equivalent to super(CurrentClass, self).method(arg)—which was the only way it could be done in Python 2—making it no longer necessary to specify it at all when making calls to superclass methods.
So what's happening, since you passed it in your code, is that it gets interpreted as overriding the default value specified for the parentParam argument.
Here's doing it properly and the result:
class Parent:
def __init__(self, parentParam="parent param"):
self.parentParam = parentParam
class Child(Parent):
def __init__(self, childParam="child param"):
self.childParam = childParam
super().__init__() # NO NEED TO PASS self.
child = Child()
print(child.childParam) # -> child param
print(child.parentParam) # -> parent param
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