2

I am trying to create a new MyClass instance in MyClass's definition.

Why does this code fail and how can achieve it?

class MyClass:
        def __init__(self):
                self.child=MyClass()

mc=MyClass()
6
  • 1
    You can't. What are you actually trying to do? Commented Sep 2, 2011 at 12:47
  • I am creating a tree, which can have children. And they are of the same class. Commented Sep 2, 2011 at 12:51
  • 1
    This approach would loop endlessly (if it would work). Commented Sep 2, 2011 at 13:03
  • 1
    They can have children. If you create it in a constructor like that it they will always have children. You should assign self.child = None and only assign self.child to something when they should have children. Commented Sep 2, 2011 at 13:45
  • 1
    As a side note, it is best always to create new classes inheriting from object rather than nothing (class MyClass(object):...) so that you're using new-style classes. Commented Sep 2, 2011 at 13:55

4 Answers 4

7

Well, it fails because it has infinite recursion. Think about it, if every MyClass has a child which is a MyClass, it will go on for infinity!

You can resolve this a couple of ways. First, you can have a parameter to the constructor:

class MyClass:
   def __init__(self, create = True):
      if create:
         self.child = MyClass(False)

mc = MyClass()

Or, you can have another, external method:

class MyClass:
    def set_child(self,child = None):
        # I prefer to make child optional for ease of use.
        child = MyClass() if child is None else child
        self.child=child

mc=MyClass()
mc.set_child()

I personally prefer the first solution as it means that outside objects don't need to know anything about the class. Of course, you could combine the two:

class MyClass:
    def __init__(self, create):
        if create:
            self.set_child(create=False)

    def set_child(self,child = None, create = True):
        child = MyClass(create) if child is None else child
        self.child=child

mc=MyClass()

This way mc has a child by default and you have the option of setting the child whenever you like.

Then there is also the "let's create a certain number" approach:

class MyClass:
    def __init__(self, count = 10):
        count -= 1
        if count:
           # the first child gets the value 9.
           # the second gets 8.
           # when the count gets to 0, stop!
           self.child = MyClass(count)

Aside: If you want to get an object's class, you can use the value obj.__class__. That will output MyClass in all of the examples above.

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

1 Comment

Quite comprehensive and illustrative.
5

You're making an infinitely recursing call — MyClass is creating another MyClass during initialization, and thus it recurses infinitely.

You may want to do something like:

class MyClass:
    def create_child(self):
        self.child=MyClass()

mc=MyClass()
mc.create_child()

If you're feeling particularly naughty, you could try:

class MyClass(object):
    @property
    def child(self):
        if self._child is None: self._child = MyClass()
        return self._child

    def __init__(self):
        self._child=None

mc=MyClass()

4 Comments

MyClass is creating another MyClass. I do not quite understand it. Can you explain it more? The code you provide is useful, thanks.:-)
Oh, it makes sense to me now. :-)
Asides, can you tell what the usage of @property is called? Thanks. It is new to me.
1

What you did there is actualy recursive, the new isntance of MyClass will create a new instance that will in turn create a new one, etc ... Soo I supose that is why your code fails, I can't tell for sure since you didn't post the error message.

Comments

1

I suggest to define two classes:

class MyClass(object):
    def __init__(self):
        self.child = MyChildClass()
    ...many other methods...

class MyChildClass(MyClass):
    def __init__(self):
        pass

I think that if two classes must behave in two different ways, they must be different (although one can subclass the other)

1 Comment

This seems precarious and unnecessary to me.

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.