1

I would like to modify an initializer of a class at run-time. Are there any potential catches with a code like this? I'm new into decorators so not really sure.

class Object:
    def __init__(self):
        print "do something"
    @classmethod
    def modify(cls, f):
        __init___old = cls.__init__
        def __init__(self):
            __init___old(self)
            f(self)
        cls.__init__ = __init__
        return f

@Object.modify
def f(self):
    print "do something else"
2
  • 1
    That makes no sense. Why is this implemented as a decorator? What exactly (in the broader context) are you trying to do? Commented Jul 29, 2014 at 15:34
  • I want to implement the register-handler-with-decorator model at the class level rather than instance level. Also, in my actual code, the function gets wrapped, I just wanted to make the question about the element of my code I wasn't sure of. Commented Jul 29, 2014 at 16:39

2 Answers 2

2

Apart from confusing people who aren't used to python's powerful meta programming facilities, things like you do should work fine. Class is modifiable is a feature of python.

However, I would suggest to find a more conventional way to do what you needed to do, meta programming causes the source code on file to no longer match what a cursory inspection of the code suggest that the code do, so it is not very good for readability. For this particular case, you could append to a list in a class variable to be called in a loop in __init__.

The only catch you may or may not experience is that if you use a python optimizing compiler, e.g. psyco, pypy, using dynamic features like this may cause them to not be able to optimize things as well as they would otherwise be able to.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I didn't think of using a class variable, that's much cleaner.
2

Rather than redefining __init__ like this, make your class keep a list of functions (which can be augmented) that should be executed at object initialization time.

class Object:
    obj_initializers = []
    def __init__(self):
        print "do something"
        for f in self.obj_initializers:
            f(self)

    @classmethod
    def add_initializer(cls, f):
        cls.obj_initializers.append(f)

def f(self):
    print "do something else"

Object.add_initializer(f)

In your code, f isn't actually modified; you are just abusing the decorator syntax to execute another function with f as an argument.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.