Builtins mit eigenen Datentypen überschreiben

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.
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Builtins mit eigenen Datentypen überschreiben

Beitragvon Leonidas » Dienstag 21. Dezember 2004, 13:15

Servus!
Mich würde interessieren, ob, und wenn dann wie, es möglich wäre, wenn ich eine Klasse von int ableite, ich die neue int Klasse als 'standard'-int einstellen kann. Also wenn das nächste mal ein int erstellt wird, dass es dann mein neuer int ist. Ich kann es ja mit

Code: Alles auswählen

ni = NewInt(10)
realisieren, aber das ist witzlos.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 21. Dezember 2004, 14:44

Hi Leonidas,

du könntest mal versuchen setattr(__builtins__, "int", NewInt) ist aber nicht getestet und IMHO auch nicht wirklich zu empfehlen.


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 21. Dezember 2004, 14:56

Dookie hat geschrieben:du könntest mal versuchen setattr(__builtins__, "int", NewInt) ist aber nicht getestet und IMHO auch nicht wirklich zu empfehlen.

Ich habe mir schon gedacht, dass sowas nicht zu empfehlen ist, aber ich wollte mal sehen ob es überhaupt möglich ist. Ich habe schon daran gedacht int() zu überschriben, per from modul import NewInt as int, aber das hat leider genausow wenig funktioniert wie die setattr Methode. Scheinbar ruft Python zum Erstellen von Strings int() gar nicht erst auf. Gibt es noch andere Möglichkeiten, oder muss ich mich geschlagen geben?
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 21. Dezember 2004, 15:49

Das liegt wohl daran, daß ints schon beim parsen erzeugt werden. Du könntest noch den Pythonsource ändern und Python selber compilieren, aber ob das so sinnvoll ist?

Btw. was kann dein Int, was der interne nicht kann?


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 21. Dezember 2004, 16:27

Dookie hat geschrieben:Das liegt wohl daran, daß ints schon beim parsen erzeugt werden. Du könntest noch den Pythonsource ändern und Python selber compilieren, aber ob das so sinnvoll ist?

Nein, das liegt nicht in meinem Sinne.

Dookie hat geschrieben:Btw. was kann dein Int, was der interne nicht kann?
Zum Glück noch nichts, denn sonst hätte ich zuviel Zeit in ein unrealisierbares Projekt gesteckt. Ich habe mir überlegt, den ints len() und ähnliches hinzuzufügen, so wie es in Ruby ja ist statt len() aufzurufen. Ja klar, die Mitarbeit mit len() kann man mit den ganzen magischen Methoden erreichen, aber objekt.len() finde ich vom Konzept her objektorientierter als len(objekt). Klar, ich kann einen neuen Datentyp machen, der das macht, aber dann müsste man etwas anderen Code schreiben, d.h. statt i = 0 wäre es dann i = NewInt(0) und bevor ich sowas mache überlege ich mir lieber erst noch einen anderen Weg. Außerdem wollte ich es als Proof-of-Concept machen (nachdem ich goto für Python gesehen habe), aber das ist scheinbar nicht so einfach.

Naja, gut, so wichtig ist es nicht, war nur eine spontane Idee von mir.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 21. Dezember 2004, 18:57

hmm len für ints? Hat für mich wenig Sinn, da len ja für die Anzahl von Elementen steht die in einer Sammlung (tuple, list, str, ...) enthalten ist.
Bei Sammlungen kannst Du ja auch alternativ z.B. liste.__len__() aufrufen. len macht ja auch nichts anderes.
Wir könnten aber eine Anregung an die Pythonmacher senden, daß Sammlungen ein Property len bekommen. In Python3 gibts das dann vielleicht.


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 21. Dezember 2004, 19:24

Dookie hat geschrieben:hmm len für ints? Hat für mich wenig Sinn, da len ja für die Anzahl von Elementen steht die in einer Sammlung (tuple, list, str, ...) enthalten ist.

Ja, das war ja nur ein Beispiel, ich würde auch andere Typen Wrappen, die auch durch len() unterstützt werden.

Dookie hat geschrieben:Bei Sammlungen kannst Du ja auch alternativ z.B. liste.__len__() aufrufen. len macht ja auch nichts anderes.

Ja, aber das ist ja wohl unpraktisch.

Dookie hat geschrieben:Wir könnten aber eine Anregung an die Pythonmacher senden, daß Sammlungen ein Property len bekommen. In Python3 gibts das dann vielleicht.

Meinst du das macht Sinn? Ich denke das wurde sicher schon mehrmals in python-dev diskutiert.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Dienstag 21. Dezember 2004, 19:52

Hi!

Ein Feature von Ruby (von dem viele Ruby-Programmierer begeistert sind) ist ja, daß man Funktionen von Builtinklassen überschreiben oder hinzufügen kann. z.B:

Code: Alles auswählen

class Array
   def len
      p "Laenge"
   end
   def greet
      p "Das Array sagt hallo"
   end
end

x = [1,2,3]
x.greet
x.len

Gut, das Beispiel macht nicht viel Sinn (eigentlich gar keinen :wink:), aber das ist doch ungefähr was Leonidas will, oder? So etwas geht in Python nicht wirklich, oder?

Gruß, mawe
Benutzeravatar
Dookie
Python-Forum Veteran
Beiträge: 2010
Registriert: Freitag 11. Oktober 2002, 18:00
Wohnort: Salzburg
Kontaktdaten:

Beitragvon Dookie » Dienstag 21. Dezember 2004, 19:54

Jo in Python geht das zum Glück nicht so. Wenn da jeder die Methoden bei Builtins mit seinen eigenen überschreibt, ist der Code bald nicht mehr lesbar, Perl lässt grüssen ;)


Gruß

Dookie

Code: Alles auswählen

#!/usr/bin/env python
import this
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Beitragvon mawe » Dienstag 21. Dezember 2004, 19:58

Hi Dookie!

Ja, bin ganz Deiner Meinung. Mir ist auch noch nie in den Sinn gekommen so etwas zu machen, man siehts aber sehr oft in Rubycode.

Gruß, mawe
Benutzeravatar
Leonidas
Administrator
Beiträge: 16023
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Beitragvon Leonidas » Dienstag 21. Dezember 2004, 21:02

Ja... okay, das mit __len__ und len() ist eigentlich auch ein Kritikpunkt von Ruby Programmierern, wenngleich vermutlich nur ein kosmetischer. Sind Rubyprogramme jetzt durch die überschriebenen builtins schlechter? Was ich doof finde, ist dass man mit from module import * problemlos oder eher komentarlos Python Builtins überschreiben kann.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
murphy
User
Beiträge: 60
Registriert: Samstag 30. Oktober 2004, 01:34
Wohnort: Berlin
Kontaktdaten:

Beitragvon murphy » Mittwoch 25. Mai 2005, 12:37

Dookie hat geschrieben:Jo in Python geht das zum Glück nicht so. Wenn da jeder die Methoden bei Builtins mit seinen eigenen überschreibt, ist der Code bald nicht mehr lesbar, Perl lässt grüssen ;)
stimmt; auch in der Ruby-community gibt es starke gegner dieser technik, und es gilt als "nicht sauber". aber mit Perl hat das sicher nichts zu tun.

mawe hat geschrieben:Ja, bin ganz Deiner Meinung. Mir ist auch noch nie in den Sinn gekommen so etwas zu machen, man siehts aber sehr oft in Rubycode.
das hat gründe: es macht vieles nämlich sehr einfach.

beispiel: ich möchte das interface zur ZLib-bibliothek (= gzip) vereinfachen.

Code: Alles auswählen

class String
   # Returns the string, unzipped.
   # See GZip.gunzip
   def gunzip
      GZip.gunzip self
   end
   
   # Returns the string, zipped.
   # +level+ is the gzip compression level, see GZip.gzip.
   def gzip level = GZip::DEFAULT_GZIP_LEVEL
      GZip.gzip self, level
   end
end
jetzt brauche ich nur noch zu schreiben:

Code: Alles auswählen

'Hallo Welt!'.gzip
ich sehe keine gefahr für den code.

in kleinen skripten ist es auch nützlich, to_s (__str__) überschreiben zu können. oder man baut sich ein NAND für booleans, was Ruby ja eigentlich nicht hat. dann kann man false / true schreiben.

manchmal fehlen einem auch einfach funktionen in Ruby; es wäre viel unsauberer und verwirrender, sie nicht gleich in die zugehörige klasse zu packen:

Code: Alles auswählen

class Array
  def shuffle
    sort_by { rand }
  end
end

builtin-methoden zu überschreiben ist allerdings ein gefährliches spiel. ich habe mal * und + für Fixnum vertauscht - mit dem erfolg, dass gar nichts mehr funktionierte.

kann man in Python klassen von den basisklassen (int, dict, tuple, list, string) ableiten?
Benutzeravatar
Joghurt
User
Beiträge: 877
Registriert: Dienstag 15. Februar 2005, 15:07

Beitragvon Joghurt » Mittwoch 25. Mai 2005, 13:18

murphy hat geschrieben:kann man in Python klassen von den basisklassen (int, dict, tuple, list, string) ableiten?
Ja, zumindest seit 2.3, vielleicht ging es auch schon in 2.2

Wer ist online?

Mitglieder in diesem Forum: Bing [Bot]