Klassenvariablen erzeugen

18/05/2011 - 22:14 von Ole Streicher | Report spam
Hallo Gruppe,

wie kann ich bei einer Klasse dynamisch *Klassen*variablen bauen?

Konkret möchte ich folgendes machen: Ich habe einige Klassen, die in der Art

class Greek(SomeParent):
alpha = myfunc('alpha')
beta = myfunc('beta')
gamma = myfunc('delta')

# ...

class Latin(SomeParent)
a = myfunc('a')
b = myfunc('b')
c = myfunc('c')

#...

die ich gerne ersetzen würde durch etwas wie

class Greek(SomeParent):
for c in 'alpha', 'beta', 'gamma':
Greek.__classdict__[c] = myfunc(c)
del c

# ...

class Latin(SomeParent):
for c in 'a', 'b', 'c':
Latin.__classdict__[c] = myfunc(c)

# ...

Das funktioniert natürlich nicht: zum Einen ist die Klasse
innerhalb ihrer Definition noch nicht existent (und kann daher
nicht referenziert werden), zum Anderen gibt es kein Attribute
__classdict__. Wie kann ich das lösen?

Besonders elegant wàre es natürlich, wenn man die beiden
Definitionen zusammen legen könnte, also ein

def alfabet(name, firstchars):
# ...

mit dem man so etwas machen kann:

Greek = alfabet('Greek', ['alpha', 'beta', 'gamma'])
Latin = alfabet('Latin', ['a', 'b', 'c'])

Es müssen wirklich Klassen sein, es folgen noch diverse
Definitionen von Objektfunktionen.

Und das allernetteste wàre noch das Analogon aiuf Modulebene,
also etwa so etwas:

alfabets = [
('Greek', ['alpha', 'beta', 'gamma']),
('Latin', ['a', 'b', 'c'])
] # this comes from some external source (library)

for name, firstchars in alfabets:
__this_module__.__classes__[name] = alfabet(name, firstchars)

Mit welchem Fahrplan komme ich da am weitesten?

Viele Grüße

Ole
 

Lesen sie die antworten

#1 Thomas Rachel
19/05/2011 - 08:33 | Warnen spam
Am 18.05.2011 22:14 schrieb Ole Streicher:
Hallo Gruppe,

wie kann ich bei einer Klasse dynamisch *Klassen*variablen bauen?

Konkret möchte ich folgendes machen: Ich habe einige Klassen, die in der Art

class Greek(SomeParent):
alpha = myfunc('alpha')
beta = myfunc('beta')
gamma = myfunc('delta')

# ...

class Latin(SomeParent)
a = myfunc('a')
b = myfunc('b')
c = myfunc('c')

#...

die ich gerne ersetzen würde durch etwas wie

class Greek(SomeParent):
for c in 'alpha', 'beta', 'gamma':
Greek.__classdict__[c] = myfunc(c)
del c



Kàme an Stelle expliziter Nennung auch ein __getattr__ in Frage?

class SomeParent(...):
...
def __getattr__(self, attr):
if attr in self.allowed:
return myfunc(attr)
raise AttributeError # da bin ich mir nicht ganz sicher...
...

class Greek(SomeParent):
allowed = 'alpha', 'beta', 'gamma'
class latin(SomeParent):
allowed = 'a', 'b', 'c'

Dann würde jedoch bei jedem Attributzugriff myfunc() aufgerufen werden,
un eine Abfrage mit hasattr() funktioniert auch nicht.


Ansonsten:

def alfabet(name, firstchars):
# ...

mit dem man so etwas machen kann:

Greek = alfabet('Greek', ['alpha', 'beta', 'gamma'])
Latin = alfabet('Latin', ['a', 'b', 'c'])



sollte gehen, mit Deinem originalen SomeParent:

def alfabet(name, firstchars):
class C(SomeParent):
pass
C.__name__ = name
for fc in firstchars:
setattr(C, fc, myfunc(fc))
return C

(ungetestet)

Evtl. wàre auch *firstchars hilfreich, so daß die Syntax dann lautet:

Greek = alfabet('Greek', 'alpha', 'beta', 'gamma')
Latin = alfabet('Latin', 'a', 'b', 'c')


Und das allernetteste wàre noch das Analogon aiuf Modulebene,



Da fàllt mir jetzt spontan nix zu ein, da auch hier der Zugriff auf das
__dict__ des Moduls nicht ohne weiteres möglich ist.


Thomas

Ähnliche fragen