Mark Harrison
Mark Harrison

Reputation: 304654

Python: __setattr__ for old-style classes?

How can I perform the equivalent of __setattr__ on an old-style class?

Upvotes: 3

Views: 252

Answers (2)

Cecil Curry
Cecil Curry

Reputation: 10276

Since the original question accepts "...equivalent methods," I'd like to demonstrate the proper means of implementing the special __setattr__() method in old-style classes.

tl;dr

Use self.__dict__[attr_name] = attr_value in the __setattr__(self, attr_name, attr_value) method of an old-style class.

__setattr__() Meets Old-style Class

Interestingly, both Python 2.7 and 3 do call __setattr__() methods defined by old-style classes. Unlike new-style classes, however, old-style classes provide no default __setattr__() method. To no one's surprise, this hideously complicates __setattr__() methods in old-style classes.

In the subclass __setattr__() of a new-style class, the superclass __setattr__() is usually called at the end to set the desired attribute. In the subclass __setattr__() of an old-style class, this usually raises an exception; in most cases, there is no superclass __setattr__(). Instead, the desired key-value pair of the special __dict__ instance variable must be manually set.

Example or It Didn't Happen

Consider a great old-style class resembling the phrase "The Black Goat of the Woods with a Thousand Young" and defining __setattr__() to prefix the passed attribute name by la_:

class ShubNiggurath:
    def __setattr__(self, attr_name, attr_value):
        # Do not ask why. It is not of human purport.
        attr_name = 'la_' + attr_name

        # Make it so. Do not call
        # super(ShubNiggurath, self).__setattr__(attr_name, attr_value), for no
        # such method exists.
        self.__dict__[attr_name] = attr_value

Asymmetries in the Darkness

Curiously, old-style classes do provide a default __getattr__() method. How Python 2.7 permitted this obscene asymmetry to stand bears no thinking upon – for it is equally hideous and shameful!

But it is.

Upvotes: 0

Anand S Kumar
Anand S Kumar

Reputation: 90989

If what you want to do is set the attribute for an instance of old style class, you can use the setattr built-in function, it should work for old-style classes as well . Example -

>>> class Foo:
...     def __init__(self,blah):
...             self.blah=blah
... 
>>> foo = Foo("Something")
>>> foo.blah
'Something'
>>> setattr(foo,'blah','somethingElse')
>>> foo.blah
'somethingElse'

You should use the built-in function for instance any type of class.

Upvotes: 2

Related Questions