Alte API -> Neue API: Warnung ausgeben...

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
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Werde eine Klasse umbenennen, will aber eine Zeitlang die alte ebenfalls noch anbieten und dazu eine warnung ausgeben. Wie machen?

Hier drei Varianten:

Code: Alles auswählen

import warnings


class NeueAPI(object):
    def test(self):
        print("NeueAPI: ok\n")


class AlteAPI1(object):
    def __new__(cls, *args, **kwargs):
        warnings.warn("Du nutzt AlteAPI1 !", FutureWarning, stacklevel=2)
        return NeueAPI()


class AlteAPI2(NeueAPI):
    def __new__(cls, *args, **kwargs):
        warnings.warn("Du nutzt AlteAPI2 !", FutureWarning, stacklevel=2)
        return NeueAPI.__new__(cls, *args, **kwargs)


class AlteAPI3(NeueAPI):
    def __new__(cls, *args, **kwargs):
        warnings.warn("Du nutzt AlteAPI3 !", FutureWarning, stacklevel=2)
        return super(AlteAPI3, cls).__new__(cls, *args, **kwargs)


if __name__ == "__main__":
    NeueAPI().test()
    AlteAPI1().test()
    AlteAPI2().test()
    AlteAPI3().test()
Alle drei funktionieren. Ausgabe:
NeueAPI: ok

test.py:34: FutureWarning: Du nutzt AlteAPI1 !
AlteAPI1().test()
NeueAPI: ok

test.py:35: FutureWarning: Du nutzt AlteAPI2 !
AlteAPI2().test()
NeueAPI: ok

test.py:36: FutureWarning: Du nutzt AlteAPI3 !
AlteAPI3().test()
NeueAPI: ok
Allerdings funktioniert in meinem echten Code (ein django.models.Field) nur die erste Variante. Bei den anderen Beiden erhalte ich den Fehler: TypeError: object() takes no parameters

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Sirius3
User
Beiträge: 18335
Registriert: Sonntag 21. Oktober 2012, 17:20

@jens: die Meta-Klassen von django scheinen sich nicht so einfach täuschen zu lassen. Aber wenn Du sowieso ein NeueAPI-Objekt erzeugen willst und kein AlteAPI-Objekt, würde ich einfach eine Funktion schreiben:

Code: Alles auswählen

def AlteAPI1(*args, **kwargs):
    warnings.warn("Du nutzt AlteAPI1 !", FutureWarning, stacklevel=2)
    return NeueAPI(*args, **kwargs)
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hm. Das über eine Funktion zu machen, darauf bin ich nicht gekommen.

Erscheint mir am einfachsten. Danke!

https://github.com/jedie/django-dbprefe ... c6e4ac7729 :D

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

FutureWarning macht in diesem Kontext überhaupt keinen Sinn. Du solltest eine DeprecationWarning nutzen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Da hast du recht... aber da war irgendwas, warum ich DeprecationWarning nicht genommen hab...

Weil man sie normalerweise nicht sieht?!?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Stimmt dass tut man nicht. Du könntest aber deine eigene DeprecationWarning definieren die man sieht, wie es z.B. Django tut. Was auch immer du letztendlich tust, FutureWarning solltest du nicht nutzen weil die zum einen was anderes meint und zum anderen bei weitem nicht die Signalwirkung hat wie eine DeprecationWarning, deren Bedeutung und Konsequenzen jeder kennt.
Antworten