Suvro Jyoti Kundu
Suvro Jyoti Kundu

Reputation: 43

Why am I not getting the string but the None value

I am new in python so the question might seem silly. My code is below: edited getting the kind feedback from @Mani and @Hashir Irfan

class University:
    
    def __init__(self):
        self.__university = None
        
    def get_university(self):
        return self.__university
    
    def add_university(self, university_string):
        # can edit only this method
        self.__university = university_string
        return self.__university

def main():
    print(University().get_university()) # success, giving None
    print(University().add_university('name')) # success, giving 'name'
    print(University().get_university()) # fail: giving None but expecting 'name' 

main()

How can I get the last one as 'name', that is self.__university get fully replaced by the 'name'? (I tried both @classmethod and @staticmethod but not worked.)

Upvotes: 1

Views: 236

Answers (2)

user904963
user904963

Reputation: 1583

Something like this works:

class University:
    
    def __init__(self):
        self.__university = None
        
    def get_university(self):
        return self.__university
    
    def add_university(self, university_string):
        self.__university = university_string
        
    def __str__(self):
        return self.__university
        
    def __repr__(self):
        return self.__university
        
def main():
    u = University()
    u.add_university("Open University")
    print(u)

main()

When you tried print(University().add_university("Open University")), it always printed None, because add_university does not return anything to print. In the absence of something to print, you get None.

For example, if you initialized __university to "Default University", it would still print None. It was just tricky, because you thought __university was getting printed, and its value was None. Giving it a variable name u and writing print(u) will print something like <__main__.University object at 0x7f15e3e344c0>, which is an address in memory associated with u. Overriding the __str__ method gives print something else to print when you pass it an object of type University rather than it using the default implementation that prints an address. Here is a similar question, asking about printing an object. Here is a nice, in-depth answer to the differences between __str__ and __repr__, which both generate strings based on an object.

You might want to consider making your constructor take a university string rather than having a misleading University object that contains nothing in it, meaning it's practically misleading. Something like this would work:

class University:

    def __init__(self, university):
        self.__university = university

    def get_university(self):
        return self.__university

    def __str__(self):
        return self.__university

    def __repr__(self):
        return self.__university

def main():
    print(University("Open University"))

main()

Notice how I removed University::add_university. It's kind of a mysterious operation to add a university to something that represents the entirety of a university already. Instead, rely on your constructor setting it when you create a University, and restrict users of your class to treat a University as immutable (it cannot be changed). When things are constant in your code, it reduces bugs. If someone needs a different University, he can create a new one with the appropriate argument to its constructor.

Upvotes: 1

Hashir Irfan
Hashir Irfan

Reputation: 334

The function return nothing that is why you are getting None. Either call get_university after add_university or return in add_university

Do this

def add_university(self, university_string):
    self.__university = university_string
    return self.__university

or this

def main():
    u = University()
    u.add_university('Open University')
    print(u.get_university())

Upvotes: 2

Related Questions