I'm not 100% clear on the intent of the code, but if you are trying to 
discourage users from replacing existing attributes on the instance, you could 
try and catch it all in the __setattr__ of the class:

class Bunch(object):
    def __init__(self, *args, **kwargs):
        for key, value in kwargs.items():
            self.__testAttr(key)
            setattr(self, key, value)
    
    def __setattr__(self, key, value):
        self.__testAttr(key)
        super(Bunch, self).__setattr__(key, value)

    def __testAttr(self, key):
        if hasattr(self, key):
            raise AttributeError("API conflict: '%s' is part " \
                                 "of the '%s' API" % (key, self))

    def pretty(self):
        text = ""
        for key, value in self.__dict__.items():
            text += "%s: %s\n" % (key, value)
        return text

In this example, we just do our check any time they try and set an attribute on 
the instance. In python you can never fully prevent these types of things, 
since the language is dynamic and interpreted. But this at least prevents the 
most direct approaches.
One thing I notice in your example is that once someone sets a new attribute on 
the class, they can never change it again, since it will then fail the test the 
next time. If you want the functionality of allowing existing attributes that 
the user has added to be changed, you would need to keep track of them in a 
list of approved attributes.

 
On Sep 14, 2013, at 2:33 AM, matthew park wrote:

> Hello there,
> 
> I am learning masking case when an object is instanced in a class and if the 
> name of the object and
> method's name is same, Type error is raised. 
> 
> the code is 
> 
> class Bunch(object):
>     def __init__(self, *args, **kwargs):
>         for key, value in kwargs.items():
>             if hasattr(self, key):
>                 raise AttributeError("API conflict: '%s' is part of the '%s' 
> API" % (key, self))
>             else:
>                 setattr(self, key, value)
>                 
>     def pretty(self):
>         text = ""
>         for key, value in self.__dict__.items():
>             text += "%s: %s\n" % (key, value)
>         return text
> 
> if __name__ == "__main__":    
>     b  = Bunch(pretty=True)
> 
> 
> The point is I don't know how to set up' bunch.pretty = True '  to prove 
> mistake in the following sentences below.
>  There, the code triggered a TypeError exception because the Bunch class's 
> pretty() method was masked by a data attribute on the instance, which we then 
> attempted to call. While the Bunch class now protects this from happening 
> during object instantiation, there is nothing to prevent you from masking the 
> pretty() method simply by setting bunch.pretty = True after creating an 
> instance.
> 
> 
> Can you give me an example  code how to prove nothing to prevent the code 
> from masking pretty() method
> simple by setting bunch.pretty=True?
> 
> 
> Thank you very much for your help!
> 
> -- 
> You received this message because you are subscribed to the Google Groups 
> "Python Programming for Autodesk Maya" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to [email protected].
> To post to this group, send email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
"Python Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.

Reply via email to