Rob
Rob

Reputation: 555

Accessing instance variables, AttributeError

I have a few related questions about instance variables in Python. I will put the first (main) question in a comment inside the code itself and ask the related ones afterwards:

class Employee:

    def __init__(self, first, last, pay):
        self.first = first
        self.last = last
        self.email = first + '.' + last + '@email.com'
        self.pay = pay

    def fullname(self):
        return '{} {}'.format(self.first, self.last)

    @classmethod
    def from_string(cls, emp_str):
        first, last, pay = emp_str.split(',')
        return cls(first, last, pay)

emp_str_1 = 'John,Doe,70000'

emp_1 = Employee.from_string(emp_str_1)

print(emp_1.fullname(), emp_1.pay, emp_1.email) #<--- This works

print(emp_1.fullname().pay.email) #<--- Why can't I do this??

Also, why is it called a "str object" by the error message:

AttributeError: 'str' object has no attribute 'pay'

Isn't emp_1 an instance of Employee?

Last question, (this may just be a PyCharm issue) PyCharm does not attempt to warn me that this code will break before I try and run it, why?

Upvotes: 0

Views: 118

Answers (1)

Manikandaraj Srinivasan
Manikandaraj Srinivasan

Reputation: 3647

In Python, concatenation can be done using +

print(emp_1.fullname(), emp_1.pay, emp_1.email) # THIS WILL WORK,

because you are just passing Strings. [ NOT RELATED to this question, just additional info : In case if you integers or boolean to print, then it will fail unless you explicitly typecast it with str())

print(emp_1.fullname().pay.email) # THIS IS NOT WORKING,

because '.' operator is used to access instance methods and variables.

If you use, emp_1.fullname(), it is calling the fullname() method which is returning some string.

But if you use emp_1.fullname().pay - emp_1.fullname() is a call to the Method and fullname() method doesn't have any variables like 'pay'. So the correct way to use is emp_1.pay.

I would suggest to use print like,

print("Name :{}:, Pay :{}: , Mail :{}:".format(emp_1.fullname(), emp_1.pay, emp_1.email)) # BECAUSE format will typecast in case if your pay is INTEGER OR FLOAT

Upvotes: 3

Related Questions