Python3 super not initializing __init__ attributes - python-3.x

I have the following code snippet:
class BaseUserAccount(object):
def __init__(self):
accountRefNo = "RefHDFC001"
FIType = "DEPOSIT"
pan = "AFF34964FFF"
mobile = "9822289017"
email = "manoja#cookiejar.co.in"
aadhar = "5555530495555"
class TestUserSavingsAccount(BaseUserAccount):
def __init__(self):
super().__init__()
accountNo = "HDFC111111111111"
accountTypeEnum = "SAVINGS"
def test_create_account(self):
request_body = """\
<UserAccountInfo>
<UserAccount accountRefNo="{}" accountNo="{}"
accountTypeEnum="{}" FIType="{}">
<Identifiers pan="{}" mobile="{}" email="{}" aadhar="{}"></Identifiers>
</UserAccount>
</UserAccountInfo>
""".format(self.accountRefNo, self.accountNo, self.accountTypeEnum,
self.FIType, self.pan, self.mobile, self.email, self.aadhar)
If I run this code in the interactive shell:
>>> t = TestUserSavingsAccount()
>>> t.accountRefNo
AttributeError: 'TestUserSavingsAccount' object has no attribute 'accountRefNo'
>>> t.accountNo
AttributeError: 'TestUserSavingsAccount' object has no attribute 'accountNo'
Seeing the above behavior, it seems like the super is neither setting up values from the base class and neither the attributes of the child (accountNo, accountTypeEnum) are being set.

The way you wrote only assign those values to local variables. You need to initialize attributes of the self object instead:
class BaseUserAccount(object):
def __init__(self):
self.accountRefNo = "RefHDFC001"
self.FIType = "DEPOSIT"
self.pan = "AFF34964FFF"
self.mobile = "9822289017"
self.email = "manoja#cookiejar.co.in"
self.aadhar = "5555530495555"
class TestUserSavingsAccount(BaseUserAccount):
def __init__(self):
super().__init__()
self.accountNo = "HDFC111111111111"
self.accountTypeEnum = "SAVINGS"

Related

Tkcalendar get_date gets passed to a function but returns TypeError

Im trying to get a date from tkcalaendar and pass it to a function where it can be saved as a class varible. It works the first time when the button is pressed however the second time it returns "TypeError: 'str' object is not callable"
from tkinter import *
from tkcalendar import *
import datetime
class test_class():
selected_date = ""
def __init__(self):
self.window = Tk()
self.stu_cal = Calendar(self.window,selectmode="day",year=int(test_class.get_year()),month=int(test_class.get_month()))
self.stu_cal.grid(row=9,column=0)
self.b3 = Button(self.window,text="Select this date",bg='#B6BDC4',fg='white',command=self.add_selected_date)
self.b3.grid(row=9,column=6)
self.window.mainloop()
def add_selected_date(self):
test_class.selected_date(self.stu_cal.get_date())
#staticmethod
def get_year():
currentDateTime = datetime.datetime.now()
date = currentDateTime.date()
return date.strftime("%Y")
#staticmethod
def get_month():
currentDateTime = datetime.datetime.now()
date = currentDateTime.date()
return date.strftime("%m")
#classmethod
def selected_date(cls,cal_date):
cls.selected_date = cal_date
test_class()
You have used same name selected_date for both class variable and class method.
Suggest to rename the class method to set_selected_date():
class test_class():
selected_date = ""
def __init__(self):
self.window = Tk()
self.stu_cal = Calendar(self.window,selectmode="day",year=int(test_class.get_year()),month=int(test_class.get_month()))
self.stu_cal.grid(row=9,column=0)
self.b3 = Button(self.window,text="Select this date",bg='#B6BDC4',fg='white',command=self.add_selected_date)
self.b3.grid(row=9,column=6)
self.window.mainloop()
def add_selected_date(self):
# use new function name
test_class.set_selected_date(self.stu_cal.get_date())
#staticmethod
def get_year():
currentDateTime = datetime.datetime.now()
date = currentDateTime.date()
return date.strftime("%Y")
#staticmethod
def get_month():
currentDateTime = datetime.datetime.now()
date = currentDateTime.date()
return date.strftime("%m")
# renamed to set_selected_date
#classmethod
def set_selected_date(cls,cal_date):
cls.selected_date = cal_date

Inherit instance variable from parent class

main.py
...
person = cPerson("xyz", "ozp")
...
person.set_name("somename")
...
csystem = cSystem()
...
cperson.py
class cPerson:
def __init__(self, addr, client):
self.addr = addr
self.client = client
self.name = None
def set_name(self, name):
self.name = name
csystem.py
from cperson import cPerson
class cSystem(cPerson):
def __init__(self):
print(self.name)
Can i access self.name from the parent class in this way? I get the error message:
AttributeError: 'cSystem' object has no attribute 'name'
I do not want to initialize from the csystem class, i want the current value from the instance variable set as shown in the main program.
I am not entirely sure what you want the end result to be.
In any case is this what you are looking for?
class cPerson:
name = None
def __init__(self, addr, client):
self.addr = addr
self.client = client
#classmethod
def set_name(cls, value):
cls.name = value
class cSystem(cPerson):
def __init__(self, addr, client):
super().__init__(addr, client)
print(self.name)
person = cPerson("xyz", "ozp")
person.set_name('Jake')
csystem = cSystem("xyz", "ozp")
The above code returns 'Jake'.
A class method is a method which is bound to the class and not the object of the class. They have the access to the state of the class as it takes a class parameter that points to the class and not the object instance.
Is this what you were looking for? If not can you explain the problem in a bit more detail?

Issue while appending Class Object to a list variable in another instance of the same Class Object

I am trying to write a simple code in Python. I'm still weak at the fundamentals of Python and I'm stuck on this issue. I have an inner Class Node(). It has an attribute routeNodes in it which is a list. I am using it to store other Instances of the same Class Object(Node()). So I first initialize the Class firstNode and give it some dummy values.
Then I run a for loop for 10 iterations. In each of the iterations I create another instance of the same Node() class. I then append the firstNode object (which is again an instance of Node()) to each of these secondNode classes.
It adds the firstNode to the routeNode list variable of the secondeNode.
But it also adds firstnode object to the routenode list variable of its own class object!
The same firstNode Object gets appended to both the class objects. Why does this happen? Can I not add class objects like this? and how do I stop it from happening?
Attaching my code. You can run it in a test class and debug the "secondNode.addRouteNodes(firstNode)" line and you'll understand my problem.
class Node:
kms = 0
cumulativeKms = 0
routeNodes = []
nodeName = ""
def __init__(self, nodeName):
self.nodeName = nodeName
def setNodeName(self, nodeName):
self.nodeName = nodeName
def getNodeName(self):
return self.nodeName
def setKms(self, kms):
self.kms = kms
def getKms(self):
return self.kms
def setCumulativeKms(self, kms):
self.cumulativeKms = self.cumulativeKms + kms
def getCumulativeKms(self):
return self.cumulativeKms
def addRouteNodes(self, nodes):
self.routeNodes.append(nodes)
def getRouteNodes(self):
return self.routeNodes
firstNode = Node("first")
firstNode.setKms(0)
firstNode.setCumulativeKms(0)
for i in range(10):
secondNode = Node('new'+str(i))
secondNode.setKms(10)
secondNode.setCumulativeKms(10)
routes = firstNode.getRouteNodes()
for route in routes:
secondNode.addRouteNodes(route)
secondNode.addRouteNodes(firstNode)
print("Done")
class Node:
kms = 0
cumulativeKms = 0
routeNodes = []
nodeName = ""
These variables don't belong to each new class object created but rather are shared between the objects and hence the first class gets appended to its own routeNodes variable over here : secondNode.addRouteNodes(route).They are called class variables.
A solution would be to initialize the variables inside the constructor like below :
self.kms = 0
self.cumulativeKms = 0
self.routeNodes = []
self.nodeName = ""
These are called instance variables.You need this.
So the updated code would be :
class Node:
def __init__(self):
self.kms = 0
self.cumulativeKms = 0
self.routeNodes = []
self.nodeName = ""
def setNodeName(self, nodeName):
self.nodeName = nodeName
def getNodeName(self):
return self.nodeName
def setKms(self, kms):
self.kms = kms
def getKms(self):
return self.kms
def setCumulativeKms(self, kms):
self.cumulativeKms = self.cumulativeKms + kms
def getCumulativeKms(self):
return self.cumulativeKms
def addRouteNodes(self, nodes):
self.routeNodes.append(nodes)
def getRouteNodes(self):
return self.routeNodes
firstNode = Node()
firstNode.setNodeName("first")
firstNode.setKms(0)
firstNode.setCumulativeKms(0)
for i in range(10):
secondNode = Node()
secondNode.setNodeName('new'+str(i))
secondNode.setKms(10)
secondNode.setCumulativeKms(10)
routes = firstNode.getRouteNodes()
for route in routes:
secondNode.addRouteNodes(route)
secondNode.addRouteNodes(firstNode)
print("Done")

Object has no attribute but attribute is defined

I have defined an attribute in a custom class, but I keep receiving an AttributeError when I try to access it.
class SMainWindow(QMainWindow):
def __init__(self):
# Constructor
super(SMainWindow, self).__init__()
self.myapp = PyQtApp()
self.layout = QVBoxLayout()
self.label_text = ''
self.settings = scrudb.retrieve_settings('current')
self.competition = self.retrieve_competition()
self.set_competition(self.competition.id)
self.label = QLabel(self.label_text)
self.button_scrutineer = QPushButton('Scrutineer Competition')
self.button_comps = QPushButton('Change Competition')
self.button_comp = QPushButton('Edit Competition Details')
self.button_dancers = QPushButton('Add/Edit Competitors')
self.button_judges = QPushButton('Add/Edit Judges')
self.button_dancerGroups = QPushButton(
'Define Competitor Groups & Dances')
self.button_import = QPushButton('Import CSV')
self.button_delete = QPushButton('Delete Competition')
self.button_exit = QPushButton('Exit')
self.button_comps.clicked.connect(self.select_competition)
self.button_delete.clicked.connect(self.delete_competition)
self.button_exit.clicked.connect(self.exit_app)
if (self.competition == None):
self.disable_buttons()
self.layout.addWidget(self.label)
self.layout.addWidget(self.button_scrutineer)
self.layout.addWidget(self.button_comps)
self.layout.addWidget(self.button_comp)
self.layout.addWidget(self.button_dancers)
self.layout.addWidget(self.button_judges)
self.layout.addWidget(self.button_dancerGroups)
self.layout.addWidget(self.button_import)
self.layout.addWidget(self.button_delete)
self.layout.addWidget(self.button_exit)
self.myapp.setLayout(self.layout)
def set_competition(self, comp_id):
self.competition = scrudb.retrieve_competition(comp_id)
if (self.competition != None):
self.label_text = ('<center>Competition:<br><strong>%s</strong><br>%8s<br>%s</center>' % (self.competition.name, self.get_formatted_date(self.competition.eventDate), self.competition.location))
self.label.setText(self.label_text)
self.settings.lastComp = self.competition.id
scrudb.set_settings(self.settings)
return self.competition
else:
self.label_text = ('<center>No Competition Selected</center>')
return None
File "/Users/majikpig/mu_code/src/main/python/scruinterface1.py", line 182, in set_competition
self.label.setText(self.label_text)
AttributeError: 'SMainWindow' object has no attribute 'label'
You need to change order of fields ... in set competition function you try to access field, which you haven't defined yet.
self.set_competition(self.competition.id)
self.label = QLabel(self.label_text)

How to create a python instance that has another class object linked to it?

If I have a simple class like below:
class Usr:
def __init__(self, time_r):
self.time_range = time_r
where I want the attributetime_r to be an object of class TimeRange like below:
class TimeRange:
def __init__(self, min_time, max_time):
self.ti = min_time
self.tf = max_time
I would like to create an empty instance of Usr s = Usr and then assign the attributes later. Example: s.time_range.ti = 5 , s.time_range.tf = 10
In other words time_r in Usr should be an attribute that will automatically create an instance of TimeRange for that Usr instance
How can one link the two classes in the manner above?
you could set initializers to default values (e.g. None):
class TimeRange:
def __init__(self, min_time=None, max_time=None):
self.ti = min_time
self.tf = max_time
class Usr:
def __init__(self, time_r=None):
self.time_range = time_r if time_r is not None else TimeRange()
then:
s = Usr()
s.time_range.ti = 5
s.time_range.tf = 10
you may want to set more reasonable default values for TimeRange...

Resources