2009-05-26 9 views
3

Bei der Definition der Klasse durch „berechnet“ Namen Attribute, wie in:Klassen-Attribute mit einem „berechnet“ namen

class C(object): 
    for name in (....): 
     exec("%s = ..." % (name,...)) 

gibt es eine andere Art und Weise die zahlreichen Attributdefinitionen der Handhabung als durch einen exec? getattr (C, Name) nicht funktioniert, weil C nicht definiert ist, während des Unterrichts Bau ...

+1

BTW: Ihr Tag der "Kompilierzeit" ist auf einer Pythonfrage jarring. Compilation ist hier nicht wirklich eine wichtige Überlegung. Hier geht es darum, eine Klasse und nicht eine Code-Kompilierung zu definieren, was ein orthogonales Problem ist. –

+0

@Ned: Du hast Recht. Ich habe das Tag "compile-time" verwendet, weil der Code im Beispiel nur zur Kompilierzeit ausgeführt wird. Technisch könnte es träge ausgeführt werden, und die Notwendigkeit, die Klasse zu definieren, würde immer noch bestehen bleiben. – EOL

Antwort

11

Wie wäre:

class C(object): 
    blah blah 

for name in (...): 
    setattr(C, name, "....") 

Das heißt, tun Sie das Attribut nach der Definition festlegen.

3
class C (object): 
    pass 

c = C() 
c.__dict__['foo'] = 42 
c.foo # returns 42 
+0

Neds Antwort ist besser :) – Dan

+0

+1 für Ihr Fairplay, Dan. :) – EOL

2

Wenn Ihre gesamte Klasse wird „berechnet“, dann kann ich vorschlagen, die type aufrufbar. Dies ist besonders nützlich, wenn Ihre Originalbehälter ein dict war:

d = dict(('member-%d' % k, k*100) for k in range(10)) 
C = type('C',(), d) 

Dies würde Ihnen die gleichen Ergebnisse wie

class C(object): 
    member-0 = 0 
    member-1 = 100 
    ... 

Wenn sich Ihre Bedürfnisse sehr komplex sind, sollten metaclasses. (Tatsächlich ist type eine Metaklasse =)

+0

Dies führt zu Attributnamen, auf die mit normaler Python-Syntax nicht zugegriffen werden kann, da Bezeichner das Bindestrich-Minus-Zeichen nicht enthalten können. Es wäre besser, in diesem Beispiel '_' zu verwenden. – gerrit