[Tutor] Why do I not get an error when I mistakenly type "humdrum.sigh_strenght" instead of the correct "humdrum.sigh_strength"?
Cameron Simpson
cs at zip.com.au
Thu Jan 21 00:34:40 EST 2016
On 20Jan2016 22:34, boB Stepp <robertvstepp at 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 <cs at zip.com.au>
More information about the Tutor
mailing list