Yes, a class can contain an instance of itself, you just can't create it on initiation for the reasons described by others.
For example, this class will do it:
class A:
def __init__(self, value):
self.value = value
def setProperty(self, subvalue):
self.innerInstance = A(subvalue)
You can then instantiate it and set its inner copy of itself like this:
>>> outerInstance = A(123)
>>> outerInstance.setProperty(456)
And verify it worked with:
>>> outerInstance.innerInstance.value
456
Answer from D Maxwell on Stack OverflowYes, a class can contain an instance of itself, you just can't create it on initiation for the reasons described by others.
For example, this class will do it:
class A:
def __init__(self, value):
self.value = value
def setProperty(self, subvalue):
self.innerInstance = A(subvalue)
You can then instantiate it and set its inner copy of itself like this:
>>> outerInstance = A(123)
>>> outerInstance.setProperty(456)
And verify it worked with:
>>> outerInstance.innerInstance.value
456
This won't work, for the reason already given:
- Python sees
A(2)and callsA.__init__. A.__init__callsA(val).A(val)callsA.__init__.- GOTO 2
I assume you're doing this so that you have a log of what val has been; that is, if sometime later you decide that you want val to be 3 instead, you don't throw away the original value 2. How about:
Code
class A( object ):
@property
def val( self ):
return self.history[ -1 ]
@val.setter
def val( self, value ):
self.history.append( value )
def __init__( self, val ):
self.history = [ ]
self.val = val
Explanation
A( object ): classes should now inherit fromobject. Just because, basically.@property: this tells python that every time we ask for A.val, it should call A.val() and return the result. This is a decorator; look up thepropertybuiltin function for more information.@val.setter: this is similar to the above, but tells Python that every time we try to assign toA.valit should call the following function instead. Instead of settingA.val, it appends the value to the history list.
Understanding classes, init and self
python - Create new object (class instance) from object method - Stack Overflow
Is there a way of instantiating a class inside a class
python - Class variable that is an instance of itself - Stack Overflow
class Organism(object):
def reproduce(self):
#use self here to customize the new organism ...
return Organism()
Another option -- if the instance (self) isn't used within the method:
class Organism(object):
@classmethod
def reproduce(cls):
return cls()
This makes sure that Organisms produce more Organisms and (hypothetical Borgs which are derived from Organisms produce more Borgs).
A side benefit of not needing to use self is that this can now be called from the class directly in addition to being able to be called from an instance:
new_organism0 = Organism.reproduce() # Creates a new organism
new_organism1 = new_organism0.reproduce() # Also creates a new organism
Finally, if both the instance (self) and the class (Organism or subclasses if called from a subclass) are used within the method:
class Organism(object):
def reproduce(self):
#use self here to customize the new organism ...
return self.__class__() # same as cls = type(self); return cls()
In each case, you'd use it as:
organism = Organism()
new_organism = organism.reproduce()
why not simply use the copy module?
import copy
organism = Organism()
replica = copy.deepcopy(organism)
I have written some code and have now realised I should not have used independent functions and call them at the right time, but rather should have used classes and constructs and what not. some functions work together with other functions but do completely different things, so putting them in the same class or in parent child or sister relationship wont work or be appropriate. So is there a way of instantiating a class inside another class
I figured out the answer to the question I had that brought me to this page. Since no one has actually suggested the answer to my question, I thought I'd post it.
class k:
pass
a = k()
k2 = a.__class__
a2 = k2()
At this point, a and a2 are both instances of the same class (class k).
Just call the "type" built in using three parameters, like this:
ClassName = type("ClassName", (Base1, Base2,...), classdictionary)
update as stated in the comment bellow this is not the answer to this question at all. I will keep it undeleted, since there are hints some people get here trying to dynamically create classes - which is what the line above does.
To create an object of a class one has a reference too, as put in the accepted answer, one just have to call the class:
instance = ClassObject()
The mechanism for instantiation is thus:
Python does not use the new keyword some languages use - instead its data model explains the mechanism used to create an instance of a class when it is called with the same syntax as any other callable:
Its class' __call__ method is invoked (in the case of a class, its class is the "metaclass" - which is usually the built-in type). The normal behavior of this call is to invoke the (pseudo) static __new__ method on the class being instantiated, followed by its __init__. The __new__ method is responsible for allocating memory and such, and normally is done by the __new__ of object which is the class hierarchy root.
So calling ClassObject() invokes ClassObject.__class__.call() (which normally will be type.__call__) this __call__ method will receive ClassObject itself as the first parameter - a Pure Python implementation would be like this: (the cPython version is, of course, done in C, and with lots of extra code for cornercases and optimizations)
class type:
...
def __call__(cls, *args, **kw):
constructor = getattr(cls, "__new__")
instance = constructor(cls) if constructor is object.__new__ else constructor(cls, *args, **kw)
instance.__init__(cls, *args, **kw)
return instance
(I don't recall seeing on the docs the exact justification (or mechanism) for suppressing extra parameters to the root __new__ and passing it to other classes - but it is what happens "in real life" - if object.__new__ is called with any extra parameters it raises a type error - however, any custom implementation of a __new__ will get the extra parameters normally)
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.
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()
Given a Python class which will be instantiated only once, i.e. there will be only one object of the class. I was wondering in which cases it makes sense to create a single class instance instead of working directly with the class instead.
So it's this:
class Singleton:
'''don't bother instantiating me'''
clsvar1 = 'foo'
@classmethod
def foobar(cls, *args, **kwargs):
if condition():
cls.clsvar1 = 'bar'
versus this?
class Singleton:
'''instantiate and use me'''
def __init__(self):
self.var1 = 'foo'
def foobar(self, *args, **kwargs):
if condition():
self.var1 = 'bar'
Recommendation
I definitely would prefer the one that's intended to be instantiated. When you create a "type of thing" that implies that you create things of that type.
The motivation is to group related code and data and having an interface to it.
That said, why not just use a module since all you want is a namespace? Modules are singletons, group related code and data, and this is a bit simpler and probably would be considered more Pythonic:
var1 ='foo'
def foobar(*args, **kwargs):
global var1
if condition():
var1 = 'bar'
So the usage would be instead of:
from modules.singleton import Singleton
Singleton.foobar()
or
from modules.singleton import Singleton
the_singleton = Singleton()
the_singleton.foobar()
do this:
from modules import singleton
singleton.foobar()
I was wondering in which cases it makes sense to create a single class instance instead of working directly with the class instead.
This is one of those things that will cause a religious war if you get into it to much.
But in general a practice that I have seen many times is that class methods should concern themselves only with creating instances of that class.
If you think about what a class is, what its purpose/behaviour is, then this makes sense. The purpose of a class is to create instances of objects that are based on itself. It is a blueprint that can also build the building. A "User" class creates "user" objects. A "Dog" class creates "dog" objects etc etc
Give this is the behaviour of a class it makes sense then that methods you add to the class "X" will concern themselves with creating "x" objects.
So even if you are only ever going to need one "x" object you should still instanciate it.
Adding methods to the X class that are not related to creating instances of "x" objects can lead to confusing unexpected code. There are of course tons of examples in the real world where people have done this anyway, but like I said that path leads to religious war.