Ex43 dictionaries within classes


#1

Hi all. I’m slowly working my way through ex43 in LP3THW and am struggling, so I created my own dictionaries within classes to better understand how to utilize this method. Here’s what I created:


# Class 1 exercises

class Thing_1(object):
    print("This is Thing_1 class")

    def func1():
        print("This is func1")

    dict_1 = {
    'me': 'first',
    'bro_1': 'second',
    'sis': 'third',
    'bro_2': 'fourth'
    }

Thing_1.func1()

print(Thing_1.dict_1.get('sis'))

# Class 2 exercises

def square():
        print("I am a square")

def circle(x):
        print(f"I am a circle; this function takes one argument:x, which is set to {x}")

x = 'unknown'

class Thing_2(object):
        dict_2 = {
        'square': square(),
        'circle': circle(x)
        }

print(Thing_2.dict_2.get('square'))

Andre here is what I get when I run the script:

This is Thing_1 class
This is func1
third
I am a square
I am a circle; this function takes one argument:x, which is set to unknown
None

Why is the print function under the Thing_1 class running? I don’t think I’m directly calling it anywhere.
Why are my square() and circle() functions running. Again, I don’t think I’m calling them anywhere.
Why is print(Thing_2.dict_2.get(‘square’)) returning “none”. I thought it would return the print function within square().

Thanks.


#2

There is a couple of things going on here and ‘print’ is the culprit…

You include a print statement in the class so when you are calling Thing_1.func1() you are actually saying to Python, call Thing_1 class and run that, which it does including the print statement, then look for func1 which it does, then () call it.

It’s absolutely valid that the print statement runs.

It’s less clear in class Thing_2 but your running those defined methods outside of your class. You are also confusing print with return here, as that is what you expect your ‘square’ value in the dict to do.

The None statement is linked to this, as when you run square() you just print to screen, and don’t return a specified value. Therefore, as Python has to return something, it defaults to None.

Check this out, I think it was what you hoped to achieve?

# Class 1 exercises                                                             
                                                                                 
class Thing_1(object):                                                          
    print("This is Thing_1 class")                                              
                                                                                     
    def func1():                                                                
        print("This is func1")                                                  
                                                                                   
        dict_1 = {                                                                  
                    'me': 'first',                                                      
                    'bro_1': 'second',                                                  
                    'sis': 'third',                                                     
                    'bro_2': 'fourth'                                                   
                       }                                                                           
                                                                              
Thing_1.func1()                                                                 
                                                                                    
print(Thing_1.dict_1.get('sis'))                                                
                                                                                    
# Class 2 exercises                                                             
class Thing_2(object):                                                          
                                                                                    
     def square():                                                               
         return "I am a square"                                                  
                                                                                  
    def circle(x):                                                              
        return f"I am a circle; this function takes one argument:x, which is set to {x}" 
                                                                                   
        x = 'unknown'                                                               
                                                                                    
       dict_2 = {'square': square(),                                               
                      'circle': circle(x)}                                              
                                                                                   
print(Thing_2.dict_2.get('square'))  

#3

Ah, thank you! I just did some reading on return and print and I guess I didn’t fully understand the difference… So, every time you use Class.attribute() any print function that is under the class will run?


#4

It depends where the statement is in the code block but if you add a print statement right after the class declaration then yes.

I made a similar mistake with print / return as most of the time in the LPTHW book you are printing output so get into that habit. But the two are very different and using return by default gets you into a better mindset I find.


#5

I think @gpkesley mostly covered it but this actually threw me for a second too. The problem is you have this:

class Thing_1(object):
   print("This is Thing_1 class")

That says: “Define a class named Thing_1 and when you define it immediately call print().” If you remove that print it will stop doing that.