On 20Jan2016 22:34, boB Stepp <robertvst...@gmail.com> wrote:
My intent was to deliberately introduce an error into my class definition:

class Hmm(object):
       def __init__(self, sigh_type, sigh_strength):
           self.sigh_type = sigh_type
           self.sigh_strength = sigh_strength
       def snort(self):
           if self.sigh_strength == 'low':
               print("snort")
           elif self.sigh_strength == 'med':
               print("Snort!")
           elif self.sigh_strenght == 'high':
               print("SNORT!!!")
           else:
               print("Hmm...")
       def sigh():
           if self.sigh_type == 'quiet':
               print("pssssss")
           elif self.sigh_type == 'annoying':
               print("Whoosh!")
           elif self.sigh_type == 'loud':
               print("HEAVY SIGH!!!")
           else:
               print("HMM!!!")

I omitted "self" from the sigh() method to see what would happen plus
some other things.

Well... You've bound a function accepting no arguments to the "sigh" attribute of the class. Legal. Nonsensical perhaps, but legal.

humdrum = Hmm('quiet', 'low')
humdrum.snort()
snort
humdrum.sigh_strength = 'med'
humdrum.snort()
Snort!
humdrum.sigh_strenght = 'high'
humdrum.snort()
Snort!

At this point I wondered why my output was not "SNORT!!!".  Then I
noticed my typo.  But now I wonder why I did not get an error from
this typo?

Because your "if" statement matched the "med". So it never tried to look up "self.sigh_strenght".

humdrum.sigh_strength = 'high'
humdrum.snort()
SNORT!!!

Again, as you expected, yes?

humdrum.sigh()
Traceback (most recent call last):
 File "<pyshell#232>", line 1, in <module>
   humdrum.sigh()
TypeError: sigh() takes 0 positional arguments but 1 was given

This was my original point in doing all of this, to see what would
result if I omitted "self".  I am pretty sure the error is because the
object instance gets automatically passed to the sigh() method, but by
leaving the "self" parameter out in the method definition, I have a
mismatch between what was defined (0 parameters) and what was passed
to the method (1 argument).

Correct.

humdrum.sigh_strenght
'high'

But what about this?  It seems like I can use the humdrum arguments
outside of the Hmm class and merrily define new variables.  Why is
this?  Is this potentially useful behavior?

"humdrum" is just an object. You can assign attibutes to it at any time.

The code executing inside the class is no different to the code outside the class; Python is a dynamic language and you can do this stuff at any time.

It isn't _specificly_ useful to assign an attribute long after its normal initialisation, but it can be quite useful. But consider your initialiser:

       def __init__(self, sigh_type, sigh_strength):
           self.sigh_type = sigh_type
           self.sigh_strength = sigh_strength

By the time __init__ is called, the object already exists with a type/class and everything. All __init__ is doing is what you find unexpected later; defining new attribute values not there before. The only thing special about __init__ is that it is called automatically after an object is created. But that is all.

This is not a static language, and __init__ is not defining what fields/attributes the object possesses. It is merely setting some of them. It is executable code, not a static type definition.

Cheers,
Cameron Simpson <c...@zip.com.au>
_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to