Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating an instance of type(self) dynamically without calling __init__?

Tags:

python

copy

class

This is quite hard to explain. I have a class which should support the method copy_stateonly(). It should return a crippled version of the object which only contains the (copied) data members that I want. I hope this example explains it better:

# everything inherits from this
class SuperBase:
    def __init__(self):
        self.state_var = 3 # this should be copied into future objects
        self.non_state_var = 0 # we don't want to copy this

    def copy_stateonly(self):
        newobj = # ??????????? create instance without calling __init__
        newobj.state_var = self.state_var
        return newobj

# some clases inherit from this
class Base(SuperBase):
    def __init__(self):
        SuperBase.__init__(self)
        self.isflying = True # we want to copy this, this is state
        self.sprite = "sprites/plane_generic.png" # we must drop this

    def copy_stateonly(self):
        newobj = SuperBase.copy_stateonly(self)
        newobj.isflying = self.isflying
        return newobj

class A144fighter(Base):
    def __init__(self, teamname): # note required __init__ argument
        Base.__init__(self)
        self.colors = ["black", "grey"] # we want to copy this, this is state
        self.name = teamname # we must drop this

    def copy_stateonly(self):
        newobj = Base.copy_stateonly(self)
        newobj.colors = self.colors[:]
        return newobj

plane = A144fighter("team_blue")
plane_state = plane.copy_stateonly() # this should return an A144fighter object with only state_var, flying and colors set.

Python 2.7

like image 386
orlp Avatar asked Nov 05 '11 16:11

orlp


People also ask

How do you create an instance of a class dynamically in Python?

Classes can be dynamically created using the type() function in Python. The type() function is used to return the type of the object. The above syntax returns the type of object.

How do I create a dynamic instance?

You can use reflection to dynamically create an instance of a type, bind the type to an existing object, or get the type from an existing object and invoke its methods or access its fields and properties. If you are using attributes in your code, reflection enables you to access them.

Can I create a class without init?

Within the class definition, the constructor refers to the specific attributes and methods using the argument self. Self indicates all potential and future instances of the class. That said, we can also create a class without including the constructor __init__ and still create attributes that all objects will haves...

What is __ self __?

The self in keyword in Python is used to all the instances in a class. By using the self keyword, one can easily access all the instances defined within a class, including its methods and attributes. init. __init__ is one of the reserved methods in Python. In object oriented programming, it is known as a constructor.


2 Answers

I'm not aware of a way to create new instances of classic classes (which is what you used in your example) without calling __init__(). New instances of new-style classes (descendants of object) can be created using

object.__new__(cls)

where cls is the type of object you would like to create.

An alternative is to use copy.copy() for copying, possibly overwriting __getstate__() and __setstate__() to define what should be copied.

Edit: To create a new instance of a classic class cls without calling __init__(), you can use the following hack:

class EmptyClass:
    pass

new_instance = EmptyClass()
new_instance.__class__ = cls
new_instance.__dict__.update(whatever)
like image 50
Sven Marnach Avatar answered Oct 04 '22 20:10

Sven Marnach


Remember that every object has a attribute named __class__. If you do <object>.__class__ it, will return that object's class object (if that makes sense). The class object is callable so you can add parentheses to the end to create a new instance of that class.

newobj = self.__class__()
like image 30
Tyler Crompton Avatar answered Oct 04 '22 19:10

Tyler Crompton