xiaohan2012
xiaohan2012

Reputation: 10342

create instance of a class in the same class's definition in python

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()

Upvotes: 2

Views: 2731

Answers (4)

Don
Don

Reputation: 17636

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)

Upvotes: 1

user193476
user193476

Reputation:

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()

Upvotes: 5

cwallenpoole
cwallenpoole

Reputation: 82078

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.

Upvotes: 7

wapiflapi
wapiflapi

Reputation: 31

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.

Upvotes: 1

Related Questions