1 | ||
Editor: 127.0.0.1
Time: 2005/05/25 15:34:31 GMT+0 |
||
Note: oprava překlepu (pepr) |
changed: - Dotaz - Chci dynamicky vytvářet instance tříd. - Jsem začátečník, snažil jsem se vytvořit funkci, která by dynamicky vytvářela instance třídy. Jedna odpověď V Pythonu se instance objektů vždy vytvářejí dynamicky. Využití funkce pro vytváření instancí má smysl pouze tehdy, když funkce na základě dalších okolností rozhodne, jaká instance (jaké třídy nebo s jakým vnitřním stavem). Pak se tomu říká "class factory". V tomto případě se funkce použije čistým způsobem (nevolá se s cílem využít vedlejší efekt, ale vracenou hodnotu). Použití by vypadalo nějak takto:: class Trida1: def __str__(self): return 'instance tridy Trida1' class Trida2: def __str__(self): return 'instance tridy Trida2' def mojeClassFactory(okolnosti): if okolnosti == 7: return Trida1() elif okolnosti == 8: return Trida2() else: return None objA = mojeClassFactory(7) print 'objA:', objA objB = mojeClassFactory(8) print 'objB:', objB objC = mojeClassFactory(1) print 'objC:', objC (Okolnosti mohou samozřejmě nabývat různou podobu.) Druhá odpověď Následující příklad ukazuje princip:: class MyClass: def __init__(self, a, b, c): self.a = a self.b = b self.c = c def __str__(self): return str(self.a) + ' ' + str(self.b) + ' ' + str(self.c) class OtherClass: def __init__(self, a): self.a = a def __str__(self): return 'OtherClass instance: ' + str(self.a) def createInstance(clsname, *args): try: cls = globals()[clsname] obj = cls(*args) return obj except: print 'Unknown class: ', clsname return None #----------------------------------------------------- o1 = MyClass(1, 2, 3) print o1 o2 = createInstance('MyClass', *('a', 'b', 'c')) print o2 o3 = createInstance('OtherClass', *('x',)) print o3 o4 = createInstance('AnotherClass', *('x', 'y', 'z')) print o4 o5 = eval('MyClass')(*(5, 6, 7)) print o5 o6 = eval('MyClass')(8, 9, 10) print o6 cls = eval('MyClass') o7 = cls(11, 12, 13) print o7 =================================================== Výstup: 1 2 3 a b c OtherClass instance: x Unknown class: AnotherClass None 5 6 7 8 9 10 11 12 13 Funkce createInstance() byla nadefinována od boku. Hledá objekt definující požadovanou třídu v globálním slovníku -- viz globals(). Protože se obecně předpokládá různý počet parametrů, používá speciálnější způsob předávání parametrů sekvencí. Použití eval není tak průhledné, ale je jednodušší a má další (neukázané) možnosti. Princip spočívá v nalezení interního objektu, který reprezentuje požadovanou třídu. Přiřazením tento objekt spojím s mnou zadaným jménem (jako u ostatních proměnných). Voláním vzniká instance třídy. Při volání musím předat požadované parametry. Naznačená funkce createInstance() kombinuje jak hledání třídy (třída je reprezentována objektem), tak předávání parametrů. Poslední příklady (o6, o7) ukazují lidštější způsob předávání parametrů. Poslední příklad dělá přesně totéž, co o6. Rozdíl spočívá jen v tom, že se objekt reprezentující třídu nejdříve zapamatuje pod jménem cls. Další odpovědi? patří sem....
V Pythonu se instance objektů vždy vytvářejí dynamicky. Využití funkce pro vytváření instancí má smysl pouze tehdy, když funkce na základě dalších okolností rozhodne, jaká instance (jaké třídy nebo s jakým vnitřním stavem). Pak se tomu říká "class factory". V tomto případě se funkce použije čistým způsobem (nevolá se s cílem využít vedlejší efekt, ale vracenou hodnotu). Použití by vypadalo nějak takto:
class Trida1: def __str__(self): return 'instance tridy Trida1' class Trida2: def __str__(self): return 'instance tridy Trida2' def mojeClassFactory(okolnosti): if okolnosti == 7: return Trida1() elif okolnosti == 8: return Trida2() else: return None objA = mojeClassFactory(7) print 'objA:', objA objB = mojeClassFactory(8) print 'objB:', objB objC = mojeClassFactory(1) print 'objC:', objC
(Okolnosti mohou samozřejmě nabývat různou podobu.)
Následující příklad ukazuje princip:
class MyClass: def __init__(self, a, b, c): self.a = a self.b = b self.c = c def __str__(self): return str(self.a) + ' ' + str(self.b) + ' ' + str(self.c) class OtherClass: def __init__(self, a): self.a = a def __str__(self): return 'OtherClass instance: ' + str(self.a) def createInstance(clsname, *args): try: cls = globals()[clsname] obj = cls(*args) return obj except: print 'Unknown class: ', clsname return None #----------------------------------------------------- o1 = MyClass(1, 2, 3) print o1 o2 = createInstance('MyClass', *('a', 'b', 'c')) print o2 o3 = createInstance('OtherClass', *('x',)) print o3 o4 = createInstance('AnotherClass', *('x', 'y', 'z')) print o4 o5 = eval('MyClass')(*(5, 6, 7)) print o5 o6 = eval('MyClass')(8, 9, 10) print o6 cls = eval('MyClass') o7 = cls(11, 12, 13) print o7 =================================================== Výstup: 1 2 3 a b c OtherClass instance: x Unknown class: AnotherClass None 5 6 7 8 9 10 11 12 13
Funkce createInstance() byla nadefinována od boku. Hledá objekt definující požadovanou třídu v globálním slovníku -- viz globals(). Protože se obecně předpokládá různý počet parametrů, používá speciálnější způsob předávání parametrů sekvencí.
Použití eval není tak průhledné, ale je jednodušší a má další (neukázané) možnosti.
Princip spočívá v nalezení interního objektu, který reprezentuje požadovanou třídu. Přiřazením tento objekt spojím s mnou zadaným jménem (jako u ostatních proměnných). Voláním vzniká instance třídy. Při volání musím předat požadované parametry.
Naznačená funkce createInstance() kombinuje jak hledání třídy (třída je reprezentována objektem), tak předávání parametrů. Poslední příklady (o6, o7) ukazují lidštější způsob předávání parametrů. Poslední příklad dělá přesně totéž, co o6. Rozdíl spočívá jen v tom, že se objekt reprezentující třídu nejdříve zapamatuje pod jménem cls.
patří sem....