Seite 1 von 1
Field Annotationen?
Verfasst: Dienstag 4. November 2008, 23:13
von DatenMetzgerX
Hallo zusammen
Ich arbeite im Büro oft mit Java und dort sind Annotationen ja stark vertreten. Leider kann man jetzt in Python jedoch nur Funktionen dekorieren, oder liege ich da falsch?
Mein Problem:
Ich habe eine Model Klasse (Verwende sqlalchemy + elixir) und möchte die Edit / View / List Visuals generisch generieren. Hierfür muss ich jedoch wissen, was ich in ein Label für ein Feld reinschreiben?! Und auch ob der Wert überhaupt angezeigt werden soll.
Hierfür hätte ich mir sowas wie
@Editable(label="Titel")
titel = Field(type=Unicode(255)...)
gewünscht. Somit wüsste ich, das Feld ist mit @Editable annotiert und muss dargestellt werden und als Key für die Übersetzungen soll "Titel" verwendet werden. Alle anderen Werte wie ob der Wert null sein darf, Max Feldlänge etc. könnte ich mir ja denn aus der Field Instanz auslesen.
Gibt es so was in Python... oder suche ich nach der falschen Lösung?
Ach ja grund wieso ich nicht einfach der Feldnamen verwenden möchte ist, dass ich sonst immer eine vordefinierte DB mit den Strings ausliefern müsste. Jedoch soll sich das Programm mit der default Übersetzung selbst in die DB abfüllen wie alle anderen standart Werte.
Gruess + Dank
Micha
Re: Field Annotationen?
Verfasst: Dienstag 4. November 2008, 23:37
von Leonidas
DatenMetzgerX hat geschrieben:Ich arbeite im Büro oft mit Java und dort sind Annotationen ja stark vertreten. Leider kann man jetzt in Python jedoch nur Funktionen dekorieren, oder liege ich da falsch?
Python 3 hat auch Dekoratoren für Klassen und Annotationen in Funktionssignaturen.
DatenMetzgerX hat geschrieben:Mein Problem:
Ich habe eine Model Klasse (Verwende sqlalchemy + elixir) und möchte die Edit / View / List Visuals generisch generieren. Hierfür muss ich jedoch wissen, was ich in ein Label für ein Feld reinschreiben?! Und auch ob der Wert überhaupt angezeigt werden soll.
Hierfür hätte ich mir sowas wie
@Editable(label="Titel")
titel = Field(type=Unicode(255)...)
gewünscht. Somit wüsste ich, das Feld ist mit @Editable annotiert und muss dargestellt werden und als Key für die Übersetzungen soll "Titel" verwendet werden. Alle anderen Werte wie ob der Wert null sein darf, Max Feldlänge etc. könnte ich mir ja denn aus der Field Instanz auslesen.
Ich würde auf den Instanzen einfach irgendwelche Attribute setzen, die man dann später abfragt. Oder ist das bei dir aus irgendeinen Grund nicht machbar?
Verfasst: Mittwoch 5. November 2008, 09:51
von DatenMetzgerX
Demfall heisst es warten.
Machbar ist es, finde ich aber nicht sehr lesbar. Somit muss ich mir als Entwickler alle Werte zuerst aus der Klasse zusammen suchen (auch wenn alles evtl gleich untereinander steht. Aber dann habe ich schon mehrere Zeile für 1 Column. Emfpinde ich einfach als unesthetisch
Code: Alles auswählen
#schöner
@editable(label="Titel")
titel = Field(type=Unicode(255))
#weniger toll
titel = Field(type=Unicode(255))
titel.label = "Titel"
titel.editable = true
Aber dankschön

Verfasst: Mittwoch 5. November 2008, 09:55
von Leonidas
Naja, also so schlimm finde ich das nun wirklich nicht:
Code: Alles auswählen
@editable(label="Titel")
titel = Field(type=Unicode(255))
# vs
titel = Field(type=Unicode(255))
editable(titel, label="Titel")
Letztendlich einfach manuell dekorieren.
Verfasst: Mittwoch 5. November 2008, 10:42
von DatenMetzgerX
Hat was! Das habe ich jetzt gar nicht in betracht gezogen. Wäe eine Vorstufe für die Dekoratoren in Py3.0. Doch dies gefällt mir.
Danke vielmals!
Verfasst: Mittwoch 5. November 2008, 10:43
von sma
Ich glaube, es ist nicht gut, Modell und Darstellung so eng zu verzahnen. Das "editable" und der "Label" dienen doch bestimmt dazu, ein Eingabeformular für das entsprechende Datenobjekt zu erstellen, haben aber nichts direkt mit der Definition zu tun.
Ich würde da dann lieber sowas machen:
Code: Alles auswählen
FooForm = ModelForm(FooModel, readonly='bar,baz', exclude='foo')
Oder das andere Extrem der totalen Verzahnung:
Code: Alles auswählen
class FooModel(Model):
bar = UnicodeField(length=255, label="Bar", visible_for="Admin", editable_for="User,Guest")
Ist dir das zu viel Information in einer Zeile, erfinde eine Namenskonvention, wie zum Beispiel:
Code: Alles auswählen
class FooModel(Model):
bar = ...
bar_visibility = admin_group
bar_changeability = user_group + guest_group
bar_validator = lambda value: len(value) < 255
Das ginge zwar auch alles in Java, ist in Python aber viel leichtgewichtiger und flexibler und daher IMHO der bessere Weg. Entscheidend ist, das sagst du ja auch, wie es sich nachher liest.
Übrigens, "type" ist ein schlechter Name, da es schon eine gleichnamige Systemfunktion gibt, die man sich in einer Funktion u.U. überschreibt.
Stefan
Verfasst: Mittwoch 5. November 2008, 19:08
von Y0Gi
Ich denke nicht, dass der Name eines Keyword-Arguments irgendwas außerhalb der Callable-Definition überschreibt.
Verfasst: Mittwoch 5. November 2008, 20:56
von Qubit
DatenMetzgerX hat geschrieben: Emfpinde ich einfach als unesthetisch
Code: Alles auswählen
#schöner
@editable(label="Titel")
titel = Field(type=Unicode(255))
#weniger toll
titel = Field(type=Unicode(255))
titel.label = "Titel"
titel.editable = true
Was sich aber recht einfach implementieren lässt, ist
Code: Alles auswählen
@Editable(label='Titel')
def create_Field(args): return Editable.Field
titel = create_Field(typ='unicode(255)')
Verfasst: Mittwoch 5. November 2008, 21:03
von lunar
Y0Gi hat geschrieben:Ich denke nicht, dass der Name eines Keyword-Arguments irgendwas außerhalb der Callable-Definition überschreibt.
Der Name überschreibt das Builtin im Funktionskörper, ob das ein Problem ist, muss man selbst entscheiden. "type" gehört jetzt imho nicht zu den Builtins, die man oft verwendet, insofern sehe ich da per se kein Problem. Ein Argument namens "open" wäre da problematischer ....
Verfasst: Mittwoch 5. November 2008, 21:21
von Leonidas
Qubit hat geschrieben:Was sich aber recht einfach implementieren lässt, ist
Code: Alles auswählen
@Editable(label='Titel')
def create_Field(args): return Editable.Field
titel = create_Field(typ='unicode(255)')
Also wenn ich sowas in fremden Code sehen würde, müsste ich mir erstmal klar machen, ob der Autor das ernst meint oder ob das nur ein Witz ist.
Zum Überschreiben von Builtins: Grundsätzlich kein Problem, aber spätestens wenn es jemand erweitert und auf ein überschriebenes Builtin zugreift kann das zu seltsamen Problemen führen. Ich für meinen Teil versuche es soweit möglich zu vermeiden.
Verfasst: Mittwoch 5. November 2008, 22:51
von Qubit
Leonidas hat geschrieben:Qubit hat geschrieben:Was sich aber recht einfach implementieren lässt, ist
Code: Alles auswählen
@Editable(label='Titel')
def create_Field(args): return Editable.Field
titel = create_Field(typ='unicode(255)')
Also wenn ich sowas in fremden Code sehen würde, müsste ich mir erstmal klar machen, ob der Autor das ernst meint oder ob das nur ein Witz ist.
Hehe.., die Sprache soll doch "Fun" bringen

No magic..
Code: Alles auswählen
def Field_titel(typ):
return 'Titel Inhalt fuer '+typ
class editable_Field:
def __init__(self,args):
self.args = args
self.args['editable'] = True
class Editable:
def __init__(self,**args):
self.args = args
def __call__(self,func):
return func(self,self.args)
def Field(self,typ):
self.args['typ'] = typ
labels = {
'Titel': Field_titel
}
selected_field_type = labels.get(self.args['label'],None)
if selected_field_type: self.args['content'] = selected_field_type(typ)
else: raise Exception, 'Wrong field type'
return editable_Field(self.args)
@Editable(label='Titel')
def create_Field(self,args): return self.Field
>>>
>>> titel = create_Field(typ='unicode(255)')
>>> titel
<__main__.editable_Field instance at 0x0143C2B0>
>>> titel.__dict__
{'args': {'content': 'Titel Inhalt fuer unicode(255)', 'editable': True, 'typ': 'unicode(255)', 'label': 'Titel'}}
>>>