Posts: 6
Threads: 2
Joined: Apr 2025
Yesterday, 06:40 PM
(This post was last modified: Yesterday, 06:40 PM by Abedin.)
Hello,
I am really struggling to understand the inheritance in python classes. In particular, I am trying to figure out how to pass the outer class attributes to inner class. Below is a sample code:
class Numbers:
def __init__(self,a,b):
self.a = a
self.b = b
class Operations:
def __init__(self):
Numbers.__init__(a,b)
self.sum = self.a + self.b
self.prod = self.a * self.b
twoNumbers = Numbers(5,4)
print(twoNumbers.Operations.sum) When I run the code, I am getting an error:
Traceback (most recent call last):
File "/Users/aabedin/Downloads/test_schedule.py", line 117, in <module>
print(twoNumbers.Operations().sum)
^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/aabedin/Downloads/test_schedule.py", line 111, in __init__
Numbers.__init__(a,b)
^
NameError: name 'a' is not defined My philosophy is as follows:
I create an object from the Numbers class. Inside that class there is another class called Operations which has certain attributes, corresponding to different arithmetic operations. I would imagine that accessing the attributes of the outer class should not be a problem, if the outer class Numbers has been instantiated inside the `__init__` method of the inner class, no?
Can you please help me understand how I can access the parent attributes within the child class?
P.S I am sorry of the formatting of the code is not right, but I don't know why "Insert ode snippet" does not show the formatting.
Posts: 1,032
Threads: 16
Joined: Dec 2016
Why 2 classes?
class Numbers:
def __init__(self,a,b):
self.sum = a + b
self.prod = a * b
twoNumbers = Numbers(5,4)
print(twoNumbers.sum, twoNumbers.prod)
Posts: 6
Threads: 2
Joined: Apr 2025
(Yesterday, 07:43 PM)Axel_Erfurt Wrote: Why 2 classes?
class Numbers:
def __init__(self,a,b):
self.sum = a + b
self.prod = a * b
twoNumbers = Numbers(5,4)
print(twoNumbers.sum, twoNumbers.prod)
Thank you for the offered solution, but I am actually writing a more sophisticated code and I need to access the parent class attributes (not methods) within the child class. The snippet I posted is just an illustration of what I am trying to achieve. My actual code is very big and not suitable for posting here.
Posts: 6,792
Threads: 20
Joined: Feb 2020
11 hours ago
(This post was last modified: 17 minutes ago by deanhystad.)
I don't understand why you are defining a class inside another class. Doing so doesn't provide any kind of class relationship. Operations is not related to numbers in any way. The only thing the embedding does is force you to refer to the Numbers class to access the Operations class.
class Numbers:
def __init__(self, a, b):
self.a = a
self.b = b
class Operations:
def __init__(self, a, b):
self.numbers = Numbers(a, b)
self.sum = self.numbers.a + self.numbers.b
self.prod = self.numbers.a * self.numbers.b
two_numbers = Numbers.Operations(5, 4)
print(two_numbers.sum, two_numbers.prod) It actually makes more sense to flip it around.
class Operations:
class Numbers:
def __init__(self, a, b):
self.a = a
self.b = b
def __init__(self, a, b):
self.numbers = self.Numbers(a, b)
self.sum = self.numbers.a + self.numbers.b
self.prod = self.numbers.a * self.numbers.b
two_numbers = Operations(5, 4)
print(two_numbers.sum, two_numbers.prod) Class relationships are IS A or HAS A. An "is a" relationship is where one class inherits attributes of another. This is called inheritance. The terms used to describe the rolls of the two classes are superclass and subclass, not parent and child.
A "has a" relationship is where one class has attributes that are instances of another class. Child and parent fit better with this type of relationship. Since everything in Python is an object of some class, even numbers, strings and lists, most python classes have a "has a" relationship with some other classes. Nothing special here.
In your example there is no relationship at all between the Number and Operation classes. They know nothing at all about each other. In my second example I convert this to a "has a" relationship when an Operations object has an attribute that is a Numbers object.
For completeness, below is an example of an "is a" relationship. Numbers is a class that holds two numbers. Operations is a class that inherits the number holding attributes of Numbers and adds new behaviors, computing the product and sum of those numbers.
class Numbers:
def __init__(self, a, b):
self.a = a
self.b = b
class Operations(Numbers):
def product(self):
return self.a * self.b
def sum(self):
return self.a + self.b
ab = Operations(4, 5)
print(ab.product(), ab.sum()) Since you don't know how python classes work, maybe you should try describing in words, not code, what you are trying to achieve.
Posts: 6
Threads: 2
Joined: Apr 2025
(11 hours ago)deanhystad Wrote: I don't understand why you are defining a class inside another class. Doing so doesn't provide any kind of class relationship. Operations is not related to numbers in any way. The only thing the embedding does is force you to refer to the Numbers class to access the Operations class.
class Numbers:
def __init__(self, a, b):
self.a = a
self.b = b
class Operations:
def __init__(self, a, b):
self.numbers = Numbers(a, b)
self.sum = self.numbers.a + self.numbers.b
self.prod = self.numbers.a * self.numbers.b
two_numbers = Numbers.Operations(5, 4)
print(two_numbers.sum, two_numbers.prod) It actually makes more sense to flip it around.
class Operations:
class Numbers:
def __init__(self, a, b):
self.a = a
self.b = b
def __init__(self, a, b):
self.numbers = self.Numbers(a, b)
self.sum = self.numbers.a + self.numbers.b
self.prod = self.numbers.a * self.numbers.b
two_numbers = Operations(5, 4)
print(two_numbers.sum, two_numbers.prod) Class relationships are IS A or HAS A. An "is a" relationship is where one class inherits attributes of another. This is called inheritance. The terms used to describe the rolls of the two classes are superclass and subclass, not parent and child.
A "has a" relationship is where one class has attributes that are instances of another class. Since everything in Python is an object of some class, even numbers, strings and lists, all python classes have a "has a" relationship with some other classes. Nothing special here.
In your example there is no relationship at all between the Number and Operation classes. They know nothing at all about each other. In my second example I convert this to a "has a" relationship when an Operations object has an attribute that is a Numbers object.
For completeness, below is an example of an "is a" relationship. Numbers is a class that holds two numbers. Product is a class that inherits the number holding attributes of Numbers and adds a new attribute, computing the product of those numbers.
Since you don't know how python classes work, maybe you should try describing in words, not code, what you are trying to achieve.
Pardon my ignorance on how classes and object-oriented programming works, as the only language I had previously programmed in was Fortran :) !
OK, I was able to extract an excerpt from my code (below), which doesn't work at the moment. I don't really think posting my entire code will help in any way.
import pandas as pd
import numpy as np
courseID = 'CHEM1250'
df = pd.DataFrame({'courseid':['CHEM1250', 'CHEM1250', 'CHEM1250', 'PHYS1200', 'PHYS1200', 'BIOL1150', 'BIOL1150'], \
'coursesec':['L01', 'L02', 'L03', 'L01','L02','L01','L01'], \
'starttime':['8:00', '12:00', 'NaN', '9:00', 'NaN', '8:00', '12:00'], \
'endtime':['8:30', '12:30', '14:00', '10:00','12:00', '8:50', '13:50'], \
'instructorid':['John', 'John', 'Bob', 'Jenna', 'Michel', 'Michel', 'Alice']})
class CourseSchedule:
def __init__(self, DataFrame):
self.df= DataFrame
def _omit_nans(self, DataFrame):
return DataFrame[DataFrame.notna()]
class Course:
def __init__(self, courseName):
self.courseName = courseName
self.show = self.display_schedule()
def display_schedule(self):
return CourseSchedule._omit_nans(df[df['courseid']==self.courseName])
schedule = CourseSchedule(df)
print(schedule.Course(courseID).show) I am using a course schedule excel file as a DataFrame. I'd like to be able to create a single object out of the CourseSchedule class and then have different classes, constructed out of that original class. Inside each class, there will be methods, pertinent to that specific subclass. I also want to be able to define some parent class methods, so that I don't have to repeat code in each method of subclasses.
For example, using the schedule object, I'd like to have a Course class and inside it, there will be a number of methods pertinent to that Course class. The reason why I decided to go with a nested class inside the CourseSchedule class is because I want to logically and neatly group methods pertinent to that class. When I create the schedule object, I might want to do something with that Data Frame returned by schedule.Course('CHEM1250') . I think it is much cleaner if I was able to do schedule.Course('CHEM1250').show or e.g. schedule.Course('CHEM1250').take_smaller_subset and do something else with it. Similarly, inside the CourseSchedule , I'll have an Instructor class with its own methods, so I can do the following: schedule.Instructor('Bob').do_something . Hopefully, that explains what I am trying to achieve.
Posts: 8,160
Threads: 160
Joined: Sep 2016
6 hours ago
(This post was last modified: 6 hours ago by buran.)
The Zen of Python
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
It was already mentioned, but let me repeat - there is no benefit whatsoever in nesting classes like this. And this is not inheritance, nor parent/child relation, if this is what you think, based on your post title....
In my humble opinion your CourseShedule class is just a wrapper around a DataFrame and does not make much sense to have such class. It makes sense to have just Course class with all its attributes - schedule, instructor, etc. populated from a DataFrame at instantiation and respective methods.
Then hold all instances of Cource class in a list or similar structure OR create separate class, to hold instances of Course class e.g. in an attribute that is listr in itsel, but only if it provides any benefits
|