23

I'm trying to create a game for my little sister. It is a Virtual Pet sort of thing and the Pet has toys to play with.

I created a class Toy and want to create a function, getNewToy(name, data1, data2, data3, data4, data5).

I want this function to create a new instance of the class Toy, and I want the function to be able to be called multiple times each time creating a new instance.

In my experience you create an instance with:

class Toy:
    def __init__(self, name, data1, data2, data3, data4, data5):
        pass

myToy = Toy(myToy, 1, 2, 3, 4, 5)

then to use methods from the class with:

myToy.method1()

Seeing as I want to have the ability to have multiple toys, each with a playWith() method I want the instance to reflect the name of the Toy each time one is called.

I want the instance to be different each time I call the method getNewToy(,...) and the instance to reflect the name.

2
  • by "use a variable" do you mean create a class instance from a string? Commented Jan 26, 2010 at 0:28
  • What is the class for this Object? Do you know what different constructor methods are available with it? Commented Jan 26, 2010 at 0:29

8 Answers 8

26

Given your edit i assume you have the class name as a string and want to instantiate the class? Just use a dictionary as a dispatcher.

class Foo(object):
    pass

class Bar(object):
    pass

dispatch_dict = {"Foo": Foo, "Bar": Bar}
dispatch_dict["Foo"]() # returns an instance of Foo
Sign up to request clarification or add additional context in comments.

2 Comments

This solution requires hard-coding every class into the dictionary. I'm going to do that for my situation, but is there no way of basically getting the functionality where you have the string "Foo" and you somehow directly produce an instance of that class?
@Addem Do you assume it has been imported? Otherwise, how will it know where the class is? What will it do if there are multiple classes with the same name? If it's been imported you can just do locals()['namehere']()
12

If you haven't found it yet, here is Dive into Python's chapter on object-oriented programming.

Here are some more examples, scroll to BankAccount.


You can call a class directly to create an instance. Parameters are passed to the __init__ method.

class Tamago(object):
    def __init__(self, name):
        self.name = name

imouto = Tamago('imouto')
oba = Tamago('oba')
oba.name # 'oba'
imouto.name # 'imouto'

2 Comments

But I would like the function to be called multiple times, each creating a new instance of the clas...
default values can be set in the __init__ params: def __init__(self, name="default name")
4

You can create variable like this:

x = 10 
print(x)

Or this:

globals()['y'] = 100
print(y)

Lets create a new class:

class Foo(object):
    def __init__(self):
        self.name = 'John'

You can create class instance this way:

instance_name_1 = Foo()

Or this way:

globals()['instance_name_2'] = Foo()

Lets create a function:

def create_new_instance(class_name,instance_name):
    globals()[instance_name] = class_name()
    print('Class instance '{}' created!'.format(instance_name))

Call a function:

create_new_instance(Foo,'new_instance') #Class instance 'new_instance' created!
print(new_instance.name) #John

Also we can write generator function:

def create_instance(class_name,instance_name):
    count = 0
    while True:
        name = instance_name + str(count)
        globals()[name] = class_name()
        count += 1
        print('Class instance: {}'.format(name))
        yield True

generator_instance = create_instance(Foo,'instance_') 

for i in range(5):
    next(generator_instance)

#out
#Class instance: instance_0
#Class instance: instance_1
#Class instance: instance_2
#Class instance: instance_3
#Class instance: instance_4

print(instance_0.name) #john
print(instance_1.name) #john
print(instance_2.name) #john
print(instance_3.name) #john
print(instance_4.name) #john

#print(instance_5.name) #error.. we only created 5 instances.. 

next(generator_instance) #Class instance: instance_5
print(instance_5.name) #John  Now it works.. 

Comments

1

Let's say you have three classes: Enemy1, Enemy2, Enemy3. This is how you instantiate them directly:

Enemy1()
Enemy2()
Enemy3()

but this will also work:

x = Enemy1
x()
x = Enemy2
x()
x = Enemy3
x()

Is this what you meant?

3 Comments

I don't think this is what he meant.
@piokuc: Apparently not, given he accepted a different answer ~2.5 years ago
Yes, I think he actually meant something like p.__class__.__new__(p.__class__) (new style classes only)
1

If you just want to pass a class to a function, so that this function can create new instances of that class, just treat the class like any other value you would give as a parameter:

def printinstance(someclass):
  print someclass()

Result:

>>> printinstance(list)
[]
>>> printinstance(dict)
{}

Comments

1

Rather than use multiple classes or class inheritance, perhaps a single Toy class that knows what "kind" it is:

class Toy:
    num = 0
    def __init__(self, name, kind, *args):
        self.name = name
        self.kind = kind
        self.data = args
        self.num = Toy.num
        Toy.num += 1

    def __repr__(self):
        return ' '.join([self.name,self.kind,str(self.num)])

    def playWith(self):
        print self

def getNewToy(name, kind):
    return Toy(name, kind)

t1 = Toy('Suzie', 'doll')
t2 = getNewToy('Jack', 'robot')
print t1
t2.playWith()

Running it:

$ python toy.py 
Suzie doll 0
Jack robot 1

As you can see, getNewToy is really unnecessary. Now you can modify playWith to check the value of self.kind and change behavior, you can redefine playWith to designate a playmate:

def playWith(self, who=None):
    if who:  pass
    print self

t1.playWith(t2)

Comments

0

This is a very strange question to ask, specifically of python, so being more specific will definitely help me answer it. As is, I'll try to take a stab at it.

I'm going to assume what you want to do is create a new instance of a datastructure and give it a variable. For this example I'll use the dictionary data structure and the variable mydictionary.

mydictionary = dict()

This will create a new instance of the dictionary data structure and place it in the variable named mydictionary. Alternatively the dictionary constructor can also take arguments:

mydictionary = dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])

Finally, python will attempt to figure out what data structure I mean from the data I give it. IE

mydictionary = {'jack': 4098, 'sape': 4139}

These examples were taken from Here

Comments

-1

I think you can use eval. Something like this

def toclass(strcls):
    return eval(strcls)()

2 Comments

The usage of eval should be avoided. Also this method requires the class to be accessible under the name of the class. Suppose you want to be able to instantiate a class named Foo which is in the module bar, your function requires the user to know the exact location. What if you put the class Foo in the same module as your function at a later point or the other way around? Also your function doesn't return a class although the name suggests so.
Ya I know. There is a messup between the name and return value. Just want to give him another way to go.