global beim Erben...

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
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Samstag 7. Oktober 2006, 22:54

Ich schau mir gerade mal i18n mit PyLucid an. Bzw. schau es mir erstmal in pocoo an :)

In pocoo hängt gettext an req. Also kommt oft sowas vor: _ = req.gettext (In jeder Methode, in der man Text hat)

Ich möchte hingegen _ Klassenweit zugänglich machen. Da ich eh schon eine Basis Klasse haben, von den man erben kann, dachte ich das ich da mit global arbeiten kann. Also so:

Code: Alles auswählen

class PyLucidBaseModule(object):

    def __init__(self, request, response):
        self.request    = request
...
        global _
        _ = self.request.gettext
Wenn ich aber von dieser Klasse erbe ist _ wohl nicht wirklich global:

Code: Alles auswählen

class bsp(PyLucidBaseModule):
    def detect_page(self):
        return _("Beispiel")
So einfach geht das wohl nicht.
Ich muß ein global nochmal im __init__ machen:

Code: Alles auswählen

class bsp(PyLucidBaseModule):
    def __init__(self, *args, **kwargs):
        super(self.__class__, self).__init__(*args, **kwargs)
        global _
        _ = self.request.gettext

    def detect_page(self):
        return _("Beispiel")
Somit wird global "nicht vererbt", warum nicht?
Wie kann man es anders machen?

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 8. Oktober 2006, 00:23

Hi

Also klassenweit global ist ja self ... dein Global ist Modulweit. Du wirst wahrscheinlich die 2. Klasse in einer anderen Datei haben.

Vielleicht ist sowas über einen decorator zu machen ... ich probier mal ein wenig rum. Aber dann kannst du auch einfach _ = self._ und in der init self._ = request......

Gruss
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sonntag 8. Oktober 2006, 00:31

Mir Fehlen die Worte :x
TUFKAB – the user formerly known as blackbird
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 8. Oktober 2006, 00:38

Und warum?

Also Decorator kannste glaubs vergessen :)

Musst halt wirklich bei jeder Funktion immer _ = request.... machen.

Gruss
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sonntag 8. Oktober 2006, 09:28

rayo hat geschrieben:Also Decorator kannste glaubs vergessen :)
Nö ^^

Code: Alles auswählen

from threading import currentThread()


class TranslationPool(object):

    def __init__(self):
        self._request_pool = {}
        self.translator = self.__call__

    def __call__(self, text, plural=None, n=1):
        req = self._request_pool.get(currentThread())
        if req is None:
            raise RuntimeError('no associated request of this thread')
        if plural is not None:
            return req.translate_plural(text, plural, n)
        return req.translate_singular(text)

    def push(self, req):
        self._request_pool[currentThread()] = req

    def pop(self):
        self._request_pool.pop(currentThread(), None)

pool = TranslationPool()


def translatable(f):
    f.func_globals['_'] = pool.translator
    return f


class MyClass(PyLucidBase):

    @translatable
    def do_something(self):
        return _("FOO!!!!!111111")
Man muss nur halt bei request __init__ den in den pool pushen, und bei request ende den dort wieder raus poppen.
TUFKAB – the user formerly known as blackbird
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Sonntag 8. Oktober 2006, 09:44

Hi

Hey das ist ja nett ... ich hab f.func_globals nicht gefunden.

Danke, auch wieder mal was gelernt, jedoch nicht so oft brauchbar :)

Gruss
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Sonntag 8. Oktober 2006, 09:55

Naja, soviel wieder zum Explizit ist better than implizit. Magic-removal lässt grüßen. :roll:
So Techniken sind zwar eine sehr mächtige Sache, aber Variblen über Dekoratoren in Funktionen pushen erscheint mir etwas magic :/
My god, it's full of CARs! | Leonidasvoice vs Modvoice
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Sonntag 8. Oktober 2006, 10:22

Rechtfertigung: Ich würde sowas nie verwenden. Pocoo geht den expliziten Weg
TUFKAB – the user formerly known as blackbird
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Sonntag 8. Oktober 2006, 15:51

Die Decorator Variante erscheint mir auch recht kompliziert.

Was spricht also gegen meine global Variante?

Ich möchte einfach nur das self einspraren und eine self._("blabla") vermeiden :)

Bei pocoo ist es ja so, das in jeder Methode, in der gettext verwendet wird, als erstes ein _ = req.gettext gemacht wird. Das ist war auch implizit, aber ich finde ein wenig zu extrem implizit :)

Ansonsten würde ich dann doch ehr auf self zurück greifen, also: self._ = req.gettext machen.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Sonntag 8. Oktober 2006, 16:01

Aus welchem Grund ist das `gettext` eigentlich Attribut von einem Request-Objekt? Macht es etwas grundsätzlich anderes als `gettext.gettext()`?
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Sonntag 8. Oktober 2006, 17:28

Naja, der eine User/Request möchte DE der andere EN :)

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Moderator
Beiträge: 8461
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Montag 8. Januar 2007, 08:53

Da hab ich doch was interessantes gefunden: http://docs.turbogears.org/1.0/Internationalization
All text strings you want translated should be included in the _() function. This function is builtin to turbogears, so you don't need to import it specifically into your module, if you have already called import turbogears.

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Montag 8. Januar 2007, 23:17

"builtin to turbogears". So ein Schwachsinn.

Turbogears patcht halt die __builtin__s. So wie es auch z.B. Pylons mit seinen magischen autoglobalen Objekten macht. Geschmackssache.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Antworten