Field Annotationen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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?
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

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 :)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
DatenMetzgerX
User
Beiträge: 398
Registriert: Freitag 28. April 2006, 06:28
Wohnort: Zürich Seebach (CH)

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!
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

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
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Ich denke nicht, dass der Name eines Keyword-Arguments irgendwas außerhalb der Callable-Definition überschreibt.
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

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)')
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 ....
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Qubit
User
Beiträge: 128
Registriert: Dienstag 7. Oktober 2008, 09:07

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'}}
>>> 
Antworten