2010-01-26 7 views
14

Sto provando a creare un gioco per mia sorellina. È un genere di cose Virtual Pet e l'animale domestico ha giocattoli con cui giocare.Creazione di un'istanza di una classe con una variabile in Python

Ho creato una classe Toy e desidero creare una funzione, getNewToy(name, data1, data2, data3, data4, data5).

Voglio questa funzione per creare una nuova istanza della classe Toy e voglio che la funzione possa essere chiamata più volte ogni volta che si crea una nuova istanza.

Nella mia esperienza si crea un'istanza con:

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

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

quindi di utilizzare i metodi della classe con:

myToy.method1() 

Visto che voglio avere la possibilità di avere più giocattoli, ogni con un metodo playWith() voglio che l'istanza rifletta il nome dello Toy ogni volta che viene chiamato uno.

Desidero che l'istanza sia diversa ogni volta che chiamo il metodo getNewToy(,...) e l'istanza che riflette il nome.

+0

da "utilizzare una variabile" vuoi dire creare un'istanza di classe da una stringa? – sberry

+0

Qual è la classe per questo oggetto? Sai quali diversi metodi di costruzione sono disponibili con esso? –

risposta

14

Data la tua modifica, presumo che tu abbia il nome della classe come stringa e desideri istanziare la classe? Basta usare un dizionario come dispatcher.

class Foo(object): 
    pass 

class Bar(object): 
    pass 

dispatch_dict = {"Foo": Foo, "Bar": Bar} 
dispatch_dict["Foo"]() # returns an instance of Foo 
+0

Questa soluzione richiede l'hard-coding di ogni classe nel dizionario. Lo farò per la mia situazione, ma non c'è modo di ottenere sostanzialmente la funzionalità in cui hai la stringa "Foo" e in qualche modo produci direttamente un'istanza di quella classe? – Addem

+0

@Addem Si suppone che sia stato importato? Altrimenti, come farà a sapere dove si trova la classe? Cosa farà se ci sono più classi con lo stesso nome? Se è stato importato puoi semplicemente fare 'locals() ['namehere']()' – Mark

0

Supponiamo di avere tre classi: Enemy1, Enemy2, Enemy3. Questo è il modo di creare le istanze direttamente:

Enemy1() 
Enemy2() 
Enemy3() 

ma questo sarà anche il lavoro:

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

E 'questo quello che volevi dire?

+0

Non penso che questo sia ciò che intendeva. – piokuc

+1

@piokuc: Apparentemente no, dato che ha accettato una risposta diversa ~ 2.5 anni fa – Claudiu

+0

Sì, penso che in realtà intendesse qualcosa come 'p .__ class __.__ new __ (p .__ class __)' (solo nuove classi di stile) – piokuc

8

Se non lo hai ancora trovato, ecco Dive into Python's chapter on object-oriented programming.

Ecco altri examples, scorrere fino a BankAccount.


È possibile chiamare direttamente una classe per creare un'istanza. I parametri vengono passati al metodo __init__.

+0

Ma vorrei che la funzione fosse chiamata più volte, creando ciascuna una nuova istanza di the clas ... –

+1

Puoi, per favore prova. – Tobu

+0

i valori predefiniti possono essere impostati nei parametri '__init__':' def __init __ (self, name = "nome predefinito") ' –

0

Questa è una domanda molto strana da porre, in particolare su python, quindi essere più specifico mi aiuterà sicuramente a rispondere. Come, proverò a prenderlo a pugnalate.

Ho intenzione di assumere che cosa si vuole fare è creare una nuova istanza di una infrastruttura e dargli una variabile. Per questo esempio userò la struttura dei dati del dizionario e la variabile mydictionary.

mydictionary = dict() 

Ciò creerà una nuova istanza della struttura di dati del dizionario e la inserirà nella variabile denominata mydictionary. In alternativa il costruttore dizionario può anche prendere argomenti:

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

Infine, pitone tenterà di capire cosa struttura dati intendo dai dati dò.IE

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

Questi esempi sono stati presi da Here

-1

Penso che si possa utilizzare eval. Qualcosa di simile

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

L'uso di eval deve essere evitato. Anche questo metodo richiede che la classe sia accessibile con il nome della classe. Supponiamo che tu voglia essere in grado di istanziare una classe chiamata Foo che si trova nella barra del modulo, la tua funzione richiede all'utente di conoscere la posizione esatta. Cosa succede se metti la classe Foo nello stesso modulo della tua funzione in un secondo momento o viceversa? Anche la tua funzione non restituisce una classe sebbene il nome lo suggerisca. – DasIch

+0

Ya lo so. C'è un disordine tra il nome e il valore di ritorno. Voglio solo dargli un'altra strada da percorrere. – user247468

1

Se si desidera solo per passare una classe a una funzione, in modo che questa funzione può creare nuove istanze di quella classe, basta trattare la classe come qualsiasi altro valore che si darebbe come parametro:

def printinstance(someclass): 
    print someclass() 

Risultato:

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

Invece di utilizzare più classi o di ereditarietà di classe, forse una sola classe giocattolo che sa quello "tipo" è:

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

L'esecuzione:

$ python toy.py 
Suzie doll 0 
Jack robot 1 

Come si può vedere, getNewToy è davvero inutile. Ora è possibile modificare playWith per controllare il valore di self.kind e comportamento di cambio, è possibile ridefinire playWith per designare un compagno di giochi:

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

t1.playWith(t2) 
1

È possibile creare variabili in questo modo:

x = 10 
print(x) 

O questo:

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

Consente di creare una nuova classe:

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

È possibile creare un'istanza della classe in questo modo:

instance_name_1 = Foo() 

O in questo modo:

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

Creiamo una funzione:

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

chiamare una funzione:

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

Inoltre possiamo scrivere la funzione del generatore:

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.. 
Problemi correlati