global und import

Django, Flask, Bottle, WSGI, CGI…
Antworten
ralf58
User
Beiträge: 8
Registriert: Montag 16. August 2010, 21:27

Hallo,

es scheint so einfach, aber seit Stunden geht es nicht:
Ich muss eine in einem anderen Modul vorbelegte Globale mit einem anderen Wert belegen.
Also z.B. in django/db/models/sql/constants.py:

Code: Alles auswählen

ORDER_PATTERN = re.compile(r'\?|[-+]?[.\w]+$')
Nun stehe ich in einer Methode meiner Klasse, nachdem ich vorher importiert habe:

Code: Alles auswählen

from django.db.models.sql import constants

class MeineKlasse(...):

    def queryset(self, request):
        constants.ORDER_PATTERN = re.compile(r'\?|[-+]?[().,\w]+$')
constants liegt auch im globalen Namensraum und ist an das Modul django.db.models.sql.constants gebunden.
Greife ich später in einem anderen Modul auf ORDER_PATTERN zu, erhalten ich wieder nur die ursprüngliche Definition, das Überschreiben hat nicht funktioniert.
Eigentlich denke ich, mir sind die Zusammenhänge klar, aber dann müßte es funktionieren.

Also, weiß jemand, wo mein Denkfehler liegt?

Danke
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Sicher, dass es die gleiche Python-Interpreter-Instanz ist und dass ORDER_PATTERN nicht z.B. durch einen From-Import importiert wurde?

Was willst du überhaupt erreichen? Sieht für mich etwas komisch aus, da irgendwelche internen Pattern zu überschreiben.

Btw, hab mal kurz nachgeschaut, django.db.models.sql.compiler z.B. nutzt einen "from ...constants import *"-Import. Da müsstest du das Pattern drin auch überschreiben.
ralf58
User
Beiträge: 8
Registriert: Montag 16. August 2010, 21:27

Python-Interpreter:
Ich nutze Eclipse mit dem Pydev-plugin und bei dem Ganzen handelt es sich um ein Django-Projekt. Insofern ist es erstmal die gleiche Interpreter-Instanz, aber natürlich ein erneuter Request.
Der Import erfolgt mittels

Code: Alles auswählen

from django.db.models.sql import constants
Die Variable ORDER_PATTERN gibt es im gesamten Django-Verzeichnis nur 2 mal: die Definition und die Verwendung.

Wozu das Ganze:
Ich benötige in einer Admin-Liste eine sortierbare Spalte, die den echten Projektende-Wert anzeigt und der steht mal in der Spalte Projektende und mal in Projektverlängerung.

Dazu erzeuge ich in der Admin-Klasse eine Spalte:

Code: Alles auswählen

    def prjende_prjverl(self, obj):
        ''' Entweder Projektende nehmen oder Verlängerng'''
        return obj.prjende if obj.prjverlaengerung is None else obj.prjverlaengerung
    prjende_prjverl.short_description="Projektende inkl. Verlängerung"
    prjende_prjverl.admin_order_field="coalesce(prjverlaengerung,prjende)"
Durch das admin_order_field ist die Spalte auch sortierbar.
Die coalesce-Funktion ist so ziemlich jeder Datenbank bekannt. Die letzte Prüfung, die Django vornimmt, bevor der String an die orderBy-Klausel angehängt wird, ist die obige Pattern-Prüfung, die Komma und Klammern nicht zulässt.
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

ralf58 hat geschrieben:Python-Interpreter:
Die Variable ORDER_PATTERN gibt es im gesamten Django-Verzeichnis nur 2 mal: die Definition und die Verwendung.
Wie gesagt, in compiler.py (welches ja offensichtlich das einzige Modul ist, in dem ORDER_PATTERN Verwendung findet), wird ORDER_PATTERN per From-Import importiert. Du musst also das Attribut ORDER_PATTERN von "django.db.models.sql.compiler" aktualisieren; das Aktualisieren von "django.db.models.sql.constants" bringt gar nix weil bevor du dazu kommst ORDER_PATTERN schon nach "...compiler" "kopiert" wurde.
ralf58
User
Beiträge: 8
Registriert: Montag 16. August 2010, 21:27

vielen Dank, das war es.
Ändern musste ich es zwar als django.db.models.sql.query.ORDER_PATTERN, aber dann funktioniert es.

Was mir nie so klar war, ist der Unterschied zwischen dem reinen "import" und dem "from". Das "from" legt ja eine platte Kopie an, nur das "import" arbeitet mit der Referenz auf ein Objekt.

Deshalb mußte der Code wie folgt aussehen:

Code: Alles auswählen

import django.db.models.sql.query

# Änderung des Patterns in einer passenden Methode:
django.db.models.sql.query.ORDER_PATTERN = re.compile(r'\?|[-+]?[().,\w]+$')
Das was ich wollte, funktioniert aber trotzdem nicht, da Django nun zwar eine korrekte order_by-Klausel hat, die aber später erneut nach den Feldern auflöst. Und das geht natürlich nicht.

Danke für die Hilfe
BlackJack

@ralf58: Ich weiss nicht ob die Formulierung so glücklich gewählt ist. Es wird beim ``from`` eine "Kopie" den Namens angelegt. Ein anderes Verhalten wäre auch ziemlich komisch, denn dann würden sich ausschliesslich diese Namen anders Verhalten als alle anderen Bindungen von Namen an Objekte in der gesamten Sprache. Bei beiden ``import``-Formen hat man am Ende ein Objekt an einen lokalen Namen gebunden. Der Unterschied ist nur die Art des Objekts -- entweder ein Modul-Objekt oder was auch immer in dem importierten Modul-Objekt an den gleichen Namen gebunden war.
Antworten