[Tutor] Why do I not get an error when I mistakenly type "humdrum.sigh_strenght" instead of the correct "humdrum.sigh_strength"?

boB Stepp robertvstepp at gmail.com
Fri Jan 22 23:14:57 EST 2016


On Thu, Jan 21, 2016 at 4:57 AM, Steven D'Aprano <steve at pearwood.info> wrote:
> On Wed, Jan 20, 2016 at 09:54:32PM -0800, Danny Yoo wrote:
>
>> Just to be explicit: you are pointing out that:
>>
>>      humdrum.sigh_strenght = 'high'
>>
>> was a typo, and it would have been nice if it could be caught as an error.
>>
>> If that's the case, then yes, I agree.  Unfortunately, this isn't a
>> runtime error because Python allows us to add arbitrary attributes to
>> objects: it's a deliberate design feature.
>
> Danny is correct. And it is a useful feature too. For instance, we can
> add attributes to functions:
>
> def spam(x, y):
>     ...
>
> spam.extra_info = "whatever"

A new thing that I did not suspect I could do.  This bothers me for two reasons:

    1)  It does not seem right adding attributes to functions outside
of its definition.

    2)  spam.extra_info appears to be global:

>>> spam.extra_info = "whatever"
>>> z = 'WOW!'
>>> def print_global_stuff():
        print('z =', z)
        print('spam.extra_info =', spam.extra_info)

>>> print_global_stuff()
z = WOW!
spam.extra_info = whatever

And I imagine I am being dense about something that is quite obvious
to you:  How is this a useful feature to have?  What does it give me
that is more useful than just saying something like:

just_another_global variable = "whatever"

?

And what bothered me about my original example that started this
thread is that when my typo

humdrum.sigh_strenght = 'high'

was accepted and did not generate an error, it seemed to mean to me
that I was violating my object's data encapsulation.  It just seems to
me that I should not be able to arbitrarily add new attributes from
outside the class definition that created my object.  That seems
similar to having a class Dog, to which from outside the class'
definition, I decide to add a new Dog attribute that all dogs in this
class can now have a tail sticking out of their noses.  I have no
qualms about subclassing Dog with a MutantDog subclass, but adding new
attributes from outside the class definition?  That just does not seem
right to at this point of my understanding.  As in your function
example, I am sure that I am missing something quite obvious, but I am
just not seeing it now.

Keep in mind, that I am just now this past week starting to study
classes.  All of my programming experience has been strictly
procedural Other than dabbling in Tkinter at work.).  I have no
pre-experience with Java or C++, other than casual reading, so any
preconceptions I have come from my procedural background ages ago in
FORTRAN.


> Other advantages of this way of doing things include that you aren't
> forced to put all your initialisation code in a single, special place,
> you can factor parts of it out into alternative methods:
>
> class X:
>    def __init__(self, x):
>        self.setup(x)
>    def setup(self, x):
>        process(x)
>        self.attribute = x
>

I have seen this before and agree that this is both useful and
desirable.  But I am comfortable with this because it is happening
*inside* the class definition.

> It also means that Python doesn't require a magic "undefined" value,
> like Javascript has, or require declarations ahead of time, like static
> languages such as Pascal and C require.

I have come to enjoy this feature of Python as well!

boB


More information about the Tutor mailing list