Not able to access object member variables - python

I am new to python and am facing a strange error.
The basic idea of my demo is to perform "Constructor Overloading" in python, similar to other programming languages.
I have two files, one file that holds only the class, and another file to create objects of the class.
employee.py
class Employee:
def displayEmployee(self):
print("Name : ", self.emp_name, ", Salary: ", self.salary)
def __init__(self,id=None,salary=None,emp_name=None):
print("Constructing MyClass")
if(id is None):
self.id=101
else:
self.id = id
if(salary is None):
self.salary=20000
else:
self.salary = salary
if(emp_name is None):
self.emp_name="Default"
else:
self.emp_name = emp_name
runner.py
from employee import Employee
emp1 = Employee()
emp2 = Employee(1,3000,"Abcd")
emp1.displayEmployee();
emp2.displayEmployee();
However, now I am facing an error as
Traceback (most recent call last):
File "runner.py", line 7, in <module>
emp2.displayEmployee();
File "D:\python\Demo\employee.py", line 3, in displayEmployee
print("Name : ", self.emp_name, ", Salary: ", self.salary)
AttributeError: 'Employee' object has no attribute 'emp_name'
That means I am not able to access any of the member variables of the class in a function of the same class. This is quite puzzling to me with respect to other programming languages.
Am I doing something wrong or is this by design?
UPDATE:
Based on the recommendation I have updated the python files to the following. However, I am still facing the same error, which is also given below.
employee.py
class Employee:
def displayEmployee(self):
print("Name : ", self.emp_name, ", Salary: ", self.salary)
def __init__(self, id=101, salary=20000, emp_name="Default"):
print("Constructing MyClass")
self.id = id
self.salary = salary
self.emp_name = emp_name
runner.py
from employee import Employee
emp1 = Employee()
emp1.displayEmployee();
Error:
Traceback (most recent call last):
File "runner.py", line 6, in <module>
emp1.displayEmployee();
File "D:\python\Demo\employee.py", line 3, in displayEmployee
print("Name : ", self.emp_name, ", Salary: ", self.salary)
AttributeError: 'Employee' object has no attribute 'emp_name'

If you pass arguments that are not None they are never assigned as attributes of self. You could modify your __init__ to simply provide default values then assign them as attributes to your class
def __init__(self, id=101, salary=20000, emp_name="Default"):
print("Constructing MyClass")
self.id = id
self.salary = salary
self.emp_name = emp_name

Related

Python AttributeError: Object has no Attribute pointing to constructor error

I am getting the following error when I try to run my PersonTest script:
AttributeError: 'Employee' object has no attribute 'set_age'
This error occurred when I changed the line "self_age = age" to "self.set_age(age)" in my Person class file. When I change the line back, the error disappears but the exception for InvalidAge does not occur. The expected outcome is for my code to catch an exception when an age >120 is input by the user. I did what I believe to be the same thing with another class, Player, and accompanying test file, PlayerTest, but no such error occurred. I believe it's pointing to the constructor but I'm not sure if something isn't being passed correctly or some other issue? I've looked for spelling mistakes and indentation errors. I will include the code for the class and test that DOES work when I changed that single line as well.
The error traceback:
Traceback (most recent call last):
File "C:\Users\lsull\Documents\School\CS 119\Labs\Lab10\PersonTest.py", line 23, in
my_person = Employee(name, address, age, job_skills, yrs_worked)
File "C:\Users\lsull\Documents\School\CS 119\Labs\Lab10\Employee.py", line 13, in init
super().init(name, address, age)
File "C:\Users\lsull\Documents\School\CS 119\Labs\Lab10\Person.py", line 13, in init
self.set_age(age)
AttributeError: 'Employee' object has no attribute 'set_age'
The Person class:
from CustomExceptions import InvalidAge
class Person:
def __init__(self, name, address, age):
self._name = name
self._address = address
self.set_age(age)
# getter and setter methods for the various properties
def get_name(self):
return self._name
def set_name(self, name):
self._name = name
def get_address(self):
return self._address
def set_address(self, address):
self._address = address
def get_age(self):
return self._age
def set_age(self, age):
MIN_AGE = 0
MAX_AGE = 120
if age >= MIN_AGE and age <= MAX_AGE:
self._age = age
else:
raise InvalidAge
# instance method
def to_string(self):
return "Name: " + self._name + " Address: " + self._address + " Age: " + str(self._age)
The PersonTest script that gives me the error:
from Employee import Employee
from Student import Student
from CustomExceptions import InvalidAge
from CustomExceptions import InvalidYearsWorked
from CustomExceptions import InvalidUnits
# Try/except block
try:
name = input("Enter name: ")
address = input("Enter address: ")
age = int(input("Enter age: "))
job_skills = input("Enter job skills: ")
yrs_worked = float(input("Enter years worked: "))
# create an instance of an emplpoyee person
my_person = Employee(name, address, age, job_skills, yrs_worked)
# invoke the to_string() method and display everything
print(my_person.to_string())
name = input("\nEnter name: ")
address = input("Enter address: ")
age = int(input("Enter age: "))
major = input("Enter major: ")
units_completed = float(input("Enter units completed: "))
# create an instance of a student person
my_person = Student(name, address, age, major, units_completed)
# invoke the to_string() method and display everything
print(my_person.to_string())
# Exception handling, always go from most specific exception to most generic
except InvalidAge as e:
print("Invalid age: ", e)
except InvalidYearsWorked as e:
print("Invalid years worked: ", e)
except InvalidUnits as e:
print("Invalid units completed: ", e)
# generic exception
#except Exception as ex:
print("Generic exception: ", ex)
The Player class that had no issues when I changed the "self._number = number" to "self.set_number(number)":
from CustomExceptions import InvalidPlayerNumException
class Player:
# custom constructor. Constructors are named __init__()
def __init__(self, name, number):
# set the attributes
# note the single underscore _ before the variable name makes them protected
self._name = name
self.set_number(number) # note we call the setter method here
# getter and setter methods for the various properties
def get_name(self):
return self._name
def set_name(self, name):
self._name = name
def get_number(self):
return self._number
def set_number(self, number):
MIN_NUMBER = 1
MAX_NUMBER = 999
# Add validation to make sure number is in the expected range
if number >= MIN_NUMBER and number <= MAX_NUMBER:
self._number = number
else:
# instead of setting player number to MIN_NUMBER, raise an exception
#self._number = MIN_NUMBER # original code
raise InvalidPlayerNumException
# instance method
def to_string(self):
return "Name: " + self._name + " Number: " + str(self._number)
Finally, the PlayerTest script that runs fine with the Player class:
from BaseballPlayer import BaseballPlayer
from CustomExceptions import InvalidPlayerNumException
from CustomExceptions import InvalidBattingException
# Try/except block
try:
name = input("Enter name: ")
number = int(input("Enter number: "))
position = input("Enter position: ")
batting_avg = float(input("Enter batting average: "))
# create an instance of a baseball player
my_player = BaseballPlayer(name, number, position, batting_avg)
# invoke the to_string() method and display everything
print(my_player.to_string())
# Exception handling, always go from most specific exception to most generic
except InvalidPlayerNumException as e:
print("Invalid player number: ", e)
except InvalidBattingException as e:
print("Invalid batting avg: ", e)
# generic exception
except Exception as ex:
print("Generic exception: ", ex)

A better way to call Class Methods from List of Class Objects - Python

I was working on Python Classes and found that one cannot call class method from class object by looping through a list of such objects. Below is a sample code:
def show_student_details(*s_list):
for s in s_list:
print("Roll Number: ", s.get_roll_no())
print("Name: ", s.get_name())
print("Phone: ", s.get_phone())
print("Marks: ", s.get_marks())
The code for Student class is:
class Student:
def __init__(self, roll_no=0, name="", phone="", marks=-1):
self.__roll_no = roll_no
self.__name = name
self.__phone = phone
self.__marks = marks
def get_roll_no(self):
return self.__roll_no
def get_name(self):
return self.__name
def get_phone(self):
return self.__phone
def get_marks(self):
return self.__marks
Running this piece of code by passing some objects of Student class gives the following error:
File "main.py", line 88, in <module>
show_student_details(students)
File "main.py", line 12, in show_student_details
print("Roll Number: ", s.get_roll_no())
AttributeError: 'list' object has no attribute 'get_roll_no'
The thing I understand is that List is itself a Class and Python interprets this code as if I was calling the get_roll_no() function on List Object.
I googled this problem and found that map() and methodcaller() can be used to call the class methods but they didn't work for me.
I know that this question has been asked multiple times on StackOverflow but I think none of them solved my problem which is 'calling multiple class methods from object by selecting objects one by one from a list of class objects.'
Any help will be appreciated. Thanks in Advance.
Assuming you are passing a list of students to the function such as
([<__main__.Student object at 0x122d85990>, <__main__.Student object at 0x122d85910>],)
, you can use :
def show_student_details(*s_list):
for s in s_list[0]:
print("Roll Number: ", s.get_roll_no())
print("Name: ", s.get_name())
print("Phone: ", s.get_phone())
print("Marks: ", s.get_marks())
Because *s_list converts your input to a list. Alternatively, you should be able to just use
def show_student_details(s_list):
for s in s_list:
print("Roll Number: ", s.get_roll_no())
print("Name: ", s.get_name())
print("Phone: ", s.get_phone())
print("Marks: ", s.get_marks())

Python Showing:- TypeError: 'int' object is not callable in python While Trying to Run Code

Well, I researched and saw many posts on this but none of them let me fix my code.
I am learning python and is currently learning Object Oriented classes.
This is My Code:-
class Employee:
'Common base calss for all employees'
empCount = 0
def __init__(self,name,salary):
self.name = name
self.salary = salary
Employee.empCount += 1
def displayCount(self):
print "Total Employee %d" % Employee.empCount
def displayEmployee(self):
print "Name: ", self.name, ",Salary: ", self.salary
"This whould create first object of Employee class"
emp1 = Employee("Zara", 2000)
"This whould create second object of employee class"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount()
And then when I run it:-
Name: Zara ,Salary: 2000
Name: Manni ,Salary: 5000
Traceback (most recent call last):
File "D:/Python Programs/Object Oriented-Classes(Python 2).py", line 46, in
<module>
print "Total Employee %d" % Employee.empCount()
TypeError: 'int' object is not callable
change this
print "Total Employee %d" % Employee.empCount()
to this
print "Total Employee %d" % Employee.empCount
Look at the error.
TypeError : 'int' object is not callable
You are trying to call a class variable Employee.empCount which is an integer and thus cannot be called.
Just change it to Employee.empCount and it should print out the varialble.
You wrote "Employee.empCount()". Remember, "()" this is used to call functions.
Like you can do "Employee.displayCount()", because displayCount() is a function.
But to access variables, simply do like this:
print "Total Employee %d" % Employee.empCount

TypeError: 'str' object is not callable Python 3.6.1

I create python Project and make a class with some methods and property (variable) when I run my script the Python Interpretation tell me:
Traceback (most recent call last):
child.class#gmail.com
File "C:/.../Python_Tutorials/Object_Orinted_Programming.py", line 272, in
Child_Instance.name("child")
TypeError: 'str' object is not callable
it is the Code:
class Mother_Class:
def __init__(self,parm1,parm2):
self.name = (parm1)
self.family = (parm2)
self.full_name = (self.name + " " + self.family)
self.email = (self.name+"."+self.family+"#gmail.com")
def full_name(self,parm1,parm2):
print ("Your Full Name is: "+parm1 + "" + parm2)
class Child_Class(Mother_Class):
def name(self,name):
name = ( name )
def family(self,family):
family = ( family )
def Some_Methods(self):
print ("Some information is Here: ")
Instance = Mother_Class("mother","class")
print (Instance.full_name)
print (Instance.email)
print ("")
Child_Instance = Child_Class("child","class")
Child_Instance.name("overwriteclass")
print (Child_Instance.full_name)
What are the Problems?
The following method rewrites the method name with the value passed to the function.
def name(self,name):
name = ( name )
So, when you then try to call the "method", you're actually trying to call the string that you overwrote the method with.
Fixing is going to require a structural change of some sort because you are trying to use name as both a method name and a property name. Maybe:
def set_name(self, name):
self.name = name

Getting an attribute error in Python

I know that there are a few post on Python attribute errors but I cannot find anything to help solve my issue or how to fix it. Here is my code:
class Employee:
def __init__(self, name, ID_number, dept, job_title):
self.__name = name
self.__ID_number = ID_number
self.__dept = dept
self.__job_title_number = job_title
#set methods
def set_name(self,name):
self.__name = name
def set_ID_number(self,ID_number):
self.__ID_number = ID_number
def set_dept(self,dept):
self.__dept = dept
def set_job_title(self,job_title):
self.__job_title = job_title
#get methods
def get_name(self):
return self.__name
def get_ID_number(self):
return self.__ID_number
def get_dept(self):
return self.__dept
def get_job_title(self):
return self.__job_title
def main():
emp1 = Employee("Susan Myers", 47899, "Accounting", "Vice President")
emp2 = Employee("Mark Jones", 39119, "IT", "Programmer")
emp3 = Employee("Joy Rogers", 81774, "Manufacturing", "Engineer")
print("Information for employee 1:")
print("Name:",emp1.get_name())
print("ID:",emp1.get_ID_number())
print("Department:",emp1.get_dept())
print("Job Title:",emp1.get_job_title())
main()
The traceback that I get is: Traceback (most recent call last):
File "C:/Users....", line 48, in
main()
File "C:/Users....", line 41, in main
print("Job Title:",emp1.get_job_title())
File "C:/Users....", line 29, in get_job_title
return self.__job_title
AttributeError: 'Employee' object has no attribute '_Employee__job_title'
In __init__, you use self.__job_title_number = job_title, but then in get_job_title you use self.__job_title, which at this point hasn't been set.
You need to make your variable name consistent across all uses.
You have not declared the member in the constructor
Must change
self.__job_title_number = job_title
to
self.__job_title = job_title
In your init function inside your class you have job title as self.__job_title_number but in the getter function you return self.__job_title. You have to change one of these so they are the same.

Categories

Resources