auf self in einer Klasse verzichten

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
bbklol
User
Beiträge: 1
Registriert: Donnerstag 12. Mai 2016, 02:37

Hi,

ich habe z.B. folgende Klasse:

Code: Alles auswählen

class testKlasse
	var1	= 0
	
	def setup(self):
		print(self.var1)
		
	def __init__(self, parameter):
		self.var1 = parameter
		self.setup()
		
Gibt es eine eine Möglichkeit auf "self" zu verzichten?
Kann man in Python ähnlich wie in C++ auch eine Art namespace setzen?
Oder gibt es eine Möglichkeit irgendwie auf self vor Instanzvariablen und -Methoden zu verzichten?

MfG
bbklol
Benutzeravatar
pillmuncher
User
Beiträge: 1484
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

bbklol hat geschrieben:Gibt es eine eine Möglichkeit auf "self" zu verzichten?
Kann man in Python ähnlich wie in C++ auch eine Art namespace setzen?
Oder gibt es eine Möglichkeit irgendwie auf self vor Instanzvariablen und -Methoden zu verzichten?
Nö, gibt's nicht. Zum Glück sind die Festplatten inzwischen groß genug, um auch mit recht vielen selfs (vier Byte!) zurechtzumommen - mindestens zehn, wenn nicht noch mehr.

Außerdem: ein Objekt ist ein Namespace. Über den self-Parameter kann man auf diesen Namespace zugreifen.

Das "var1 = 0" auf Klassenebene tut vermutlich nicht, was du glaubst, dass es tut. So, wie es dasteht, ist var1 ein Klassenattribut. In anderen, altmodischeren Sprachen würde man das vielleicht eine Klassenvariable oder eine statische Variable nennen.

Versuch nicht, Konzepte aus anderen Sprachen in deinen Pythoncode einzubauen. C/C#/C++/Java/... in Python ist weder gutes C/C#/C++/Java/..., noch gutes Python.
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@bbklol:
Nein, das geht in Python nicht so wie du es von C++ kennst. Methoden sind in Python eigentlich nur Funktionen, die auf Klassen gesetzt werden und als ersten Parameter eine Klasseninstanz erwarten. `self` als erster Parameter definiert lediglich die Referenz das übergebene Objekt der Klasse. Du könntest diesen Parameter auch als `nudelsalat` definieren und hättest beim Zugriff auf `nudelsalat` innerhalb der Methode den selben Effekt. `self` wird ganz einfach per Konvention so genannt und findet sich in dieser Form in so ziemlich jedem Python-Programm mit Klassen.

Insofern kann `self` eben nicht einfach weggelassen werden, da es sich hier nicht um ein spezielles Schlüsselwort handelt, sondern um einen stinknormalen Parameter. Die einzige Magie ist, dass das besagte Klassenobjekt beim Aufruf von Methoden auf instanziierten Klassen automatisch übergeben wird.
BlackJack

@bbklol: Da in Python keine Variablen deklariert werden, der Compiler in Funktionen und Methoden einen Namen als lokal ansieht falls irgendwo im Funktionskörper eine Zuweisung an den Namen stattfindet, könnten dann Attribute und lokale Namen nicht mehr voneinander unterschieden werden. In C++ haben viele Projekte auch eine Namenskonvention für „Membervariablen“, beispielsweise ein `m`-Präfix, um sie leichter von lokalen Namen unterscheiden zu können. Das braucht man in Python wegen dem `self` nicht. Sieh's als Vorteil. :-)

Namensräume sind in Python hauptsächlich Packages, Module, und Klassen, aber letztendlich auch jedes Objekt bei dem man Attribute setzen kann. Wobei man Klassen (IMHO) nicht als reine Namensräume missbrauchen sollte.
Benutzeravatar
kbr
User
Beiträge: 1487
Registriert: Mittwoch 15. Oktober 2008, 09:27

BlackJack hat geschrieben:Wobei man Klassen (IMHO) nicht als reine Namensräume missbrauchen sollte.
Seit Python 3.3 gibt es dafür SimpleNamespace, womit man dies gut vermeiden kann.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Eine weitere Möglichkeit, auf die Schnelle zusammengehörige Attribute zu bündeln:

Code: Alles auswählen

>>> bundle = lambda: None
>>> bundle.foo = 10
>>> bundle._bar = 20
>>> bundle._bar / bundle.foo
2
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@mutetella:
Kann man machen, ist aber unsauber. Eine gängige Möglichkeit, die Importe auskommt, wäre:

Code: Alles auswählen

class Namespace:
    pass

ns = Namespace()
ns.x = 42
print(ns.x)
Inzwischen gibt es aber bekanntlich `SimpleNamespace` und `namedtuple`, die für solche Aufgaben deutlich geeigneter sind.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

@snafu
Ok… `namedtuple` fällt allerdings dann aus, wenn man Attributnamen mit führendem Unterstrich verwenden möchte. Letztlich gefällt mir die kurze und bündige Lösung mit einer Klasse am besten. Da sieht man auf einen Blick, was alles nicht d'rin ist… :wink:
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Antworten