how to solve attribute error when all attributes do exist? - python

I am writing a program for my A level course in python and i need to access an attribute from one class in to another using inheritance. here is an example of what I am trying to do.
class class1():
def __init__(self):
self.testValue = 'hello'
class class2(class1):
def __init__(self):
self.inheritedValue = class1.testValue
print(self.inheritedValue)
object = class2()
when running this code i get the following attribute error.
AttributeError: type object 'class1' has no attribute 'testValue'
anyone got a solution for this??

First a comment to code style: class names are written in CamelCase, so name them Class1 and Class2.
Secondly, your class Class1 doesn't have the said attribute, but each instance does.
So your class2 should look like
class Class2(Class1):
def __init__(self):
super().__init__() # now we have everything Class1 provides us with
self.inheritedValue = self.testValue
print(self.inheritedValue)
because each object of Class2 is also an object of Class1

The attribute does not exist within the scope of class2 the way you've implemented it. By passing it in the class definition, it is inherited but the attribute doesn't exist yet. That is, unless you've called the constructor. Two ways of doing this, by either using the super built-in function(not recommended in real life, see here, it's a nice read. Anyway, here are a few solutions:
class class1():
def __init__(self):
self.testValue = 'hello'
class class2(class1):
def __init__(self):
class1.__init__(self)
print(self.testValue)
obj = class2()
if you do not want to call the constructor of the class you are inheriting, you could do something like this:
class class1():
testValue = 'hello'
def __init__(self):
pass
class class2(class1):
def __init__(self):
self.inheritedValue = class1.testValue
print(self.inheritedValue)
obj = class2()
Side note, object is a built-in so you shouldn't use it.

Related

Why python metaclass is not working in this code?

class My_meta(type):
def hello(cls):
print("hey")
class Just_a_class(metaclass=My_meta):
pass
a = Just_a_class()
a.hello()
Above code is giving:
AttributeError: 'Just_a_class' object has no attribute 'hello'
Please suggest the changes to make it work. Thanks.
Methods in a metaclass are inherited by the class object, not class instances. You can call the function this way:
Just_a_class.hello()
// or
a = Just_a_class()
a.__class__.hello()

How does this python inheritance hierarchy work? (specific example)

I am working on a code base that uses oop and I am relavtively new to it. My question specifically is, why NewMenuItem not inherit from File?
code bunk to play with code: https://codebunk.com/b/350127244/
"""Build class hierarchy and get values from decendants"""
import inspect
def selftest():
class Menu(object):
def __init__(self):
super(Menu, self).__init__()
self.value = "Menu"
class MenuBar(Menu):
#having object in there makes it a new style object, which allows us to use super
def __init__(self):
super(MenuBar, self).__init__()
self.value = "MenuBar"
class File(MenuBar):
def __init__(self):
Menu.__init__()
super(File, self).__init__()
self.value = "File"
self.FileValue = "File here!"
class New(Menu):
def __init__(self):
Menu.__init__()
pass
class NewMenuItem(Menu):
def __init__(self):
"""
Q 1- Why do I need self here?
Menu.__init__(self)
"""
Menu.__init__(self)
pass
def show_vals(self):
print(self.value)
"""
Q 2 -why wont this work?
def show_vals2(self):
print(self.FileValue)
"""
example = File.New.NewMenuItem()
example.show_vals()
"""
Q 3 - Why do I get this error with this line?
inspect.getmro(example)
AttributeError: 'ManageProduct' object has no attribute '__bases__'
"""
I'm trying to understand what is happening line by line, but what I don't get is why NewMenuItem doesn't inherit from File.
I tried hard-coding the instantiation of File,like so:
File.init()
but then I get an error unless I pass the File object:
File.__init__(File())
I guess what I am struggling with is:
-inheritance trees
-super classes
-why we need to hard-code instantiations in this case
Keep in mind that this is the code I have come across. I am not sure why this is the way it is.
Inheritance and scope are two completely different things. NewMenuItem is defined inside the scope of the class New, inside of the scope of the class File, but it inherits from Menu, which inherits from object. So while NewMenuItem will only be accessible through the class File and again through New, it will inherit its methods from Menu, and super will refer to Menu.

Subclassing a Python class to inherit attributes of super class

I'm trying to inherit attributes from a super class but they are not being initialized correctly:
class Thing(object):
def __init__(self):
self.attribute1 = "attribute1"
class OtherThing(Thing):
def __init__(self):
super(Thing, self).__init__()
print self.attribute1
This throws an error since attribute1 is not an attribute of OtherThing, even though Thing.attribute1 exists. I thought this was the correct way to inherit and extend a super class. Am I doing something wrong? I don't want to create an instance of Thing and use its attributes, I need it to inherit this for simplicity.
You have to give, as argument, the class name (where it is being called) to super():
super(OtherThing, self).__init__()
According to Python docs:
... super can be used to refer to parent classes without naming them
explicitly, thus making the code more maintainable.
so you are not supposed to give the parent class.
See this example from Python docs too:
class C(B):
def method(self, arg):
super(C, self).method(arg)
Python3 makes this easy:
#!/usr/local/cpython-3.3/bin/python
class Thing(object):
def __init__(self):
self.attribute1 = "attribute1"
class OtherThing(Thing):
def __init__(self):
#super(Thing, self).__init__()
super().__init__()
print(self.attribute1)
def main():
otherthing = OtherThing()
main()

How to convert (inherit) parent to child class?

I would like to know how to convert parent object that was return by some function to child class.
class A(object):
def __init__():
pass
class B(A):
def functionIneed():
pass
i = module.getObject() # i will get object that is class A
j = B(i) # this will return exception
j.functionIneed()
I cannot change class A. If I could I would implement functionIneed to class A, but it is impossible because of structure of code.
Python does not support "casting". You will need to write B.__init__() so that it can take an A and initialize itself appropriately.
I have a strong suspicion, nay, conviction, that there is something horribly wrong with your program design that it requires you to do this. In Python, unlike Java, very few problems require classes to solve. If there's a function you need, simply define it:
def function_i_need(a):
"""parameter a: an instance of A"""
pass # do something with 'a'
However, if I cannot dissuade you from making your function a method of the class, you can change an instance's class by setting its __class__ attribute:
>>> class A(object):
... def __init__(self):
... pass
...
>>> class B(A):
... def functionIneed(self):
... print 'functionIneed'
...
>>> a = A()
>>> a.functionIneed()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'functionIneed'
>>> a.__class__ = B
>>> a.functionIneed()
functionIneed
This will work as long as B has no __init__ method, since, obviously, that __init__ will never be called.
You said you want to implement something like this:
class B(A):
def functionIneed():
pass
But really what you would be making is something more like this (unless you had intended on making a class or static method in the first place):
class B(A):
def functionIneed(self):
pass
Then you can call B.functionIneed(instance_of_A). (This is one of the advantages of having to pass self explicitly to methods.)
You did not correctly define your classes.
Should be like this:
class A(object):
def __init__(self):
pass
class B(A):
def __init__(self):
super(B,self).__init__()
def functionIneed(self):
pass
Then you can
j=B()
j.fuctionIneed()
as expected
You forgot to refer to the ins
Just thinking outside the box:
Instead of a new class with the function you want, how about just adding the function to the class or instance you already have?
There is a good description of this in
Adding a Method to an Existing Object Instance
How about:
i = module.getObject() # i will get object that is class A
try:
i.functionIneed()
except AttributeError:
# handle case when u have a bad object
Read up on duck typing.

Can't access parent member variable in Python

I'm trying to access a parent member variable from an extended class. But running the following code...
class Mother(object):
def __init__(self):
self._haircolor = "Brown"
class Child(Mother):
def __init__(self):
Mother.__init__(self)
def print_haircolor(self):
print Mother._haircolor
c = Child()
c.print_haircolor()
Gets me this error:
AttributeError: type object 'Mother' has no attribute '_haircolor'
What am I doing wrong?
You're mixing up class and instance attributes.
print self._haircolor
You want the instance attribute, not the class attribute, so you should use self._haircolor.
Also, you really should use super in the __init__ in case you decide to change your inheritance to Father or something.
class Child(Mother):
def __init__(self):
super(Child, self).__init__()
def print_haircolor(self):
print self._haircolor

Categories