Abfragen ob Klasseninstanz existiert

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
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi

habe zur Zeit eine Klasse, welche flexibel manchmal eine Instanz (genauer ein Instanzobjekt oder instance object) besitzt - oder nicht besitzt. Wie kann ich testen, ob es diese Instanz gibt oder nicht? Und zwar möchte ich das ohne try/except wissen, sondern in einer direkten "Look before you leap"-Manier. (So in etwa wie bei dicts mit dict.has_key().)
Grund: Das sollte in diesem Fall etwas klareren Code ergeben.

Geht das? Wie? (Ich stehe auf dem Schlauch und habe das Gefühl, daß ich mir gleich auf den Kopf hauen werde und sagen werde: "Oh, das war aber einfach!")

Gruß,
Christian
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Könntest Du nicht eine Klassenvariable nehmen, die bei Erzeugung einer Instanz incrementiert, und beim Löschen decrementiert (heisst das überhaupt so?) wird?

Code: Alles auswählen

>>> class A:
...     count = 0
...     def __init__(self): self.__class__.count += 1
...     def __del__(self): self.__class__.count -= 1
...
>>> A.count
0
>>> a = A()
>>> A.count
1
>>> del(a)
>>> A.count
0
>>>
Gruß, mawe
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Das wäre mein Code, mit einem simplen Wahrheitswert:

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-

class One(object):
    hasinstance = False
    def __init__(self):
        self.__class__.hasinstance = True
    
    def __del__(self):
        self.__class__.hasinstance = False
    
print One.hasinstance
o = One()
print One.hasinstance
del o
print One.hasinstance
Jedoch die Methode __del__ aufzurufen.. naja, bei __del__ ist es nicht gesichert ob sie aufgerufen wird. Ich habe gehört, das soll in Python 2.5 mit ContextManagern besser werden, aber ich weiß es nicht genau.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi Leonidas!

Was aber, wenn ich bei Deiner Methode 2 Objekte erstelle, und eines wieder lösche? Dann ist hasinstance = False, obwohl es noch ein Objekt gibt.

Gruß, mawe
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Vielen Dank für die Antworten, aber das zielt an dem was ich eigentlich wollte vorbei. Bei der Instanz handelt es sich 1.) um eine unter mehreren und 2.) um ein numpy-array. Mit anderen Worten: Wenn ich Rohdaten in einer best. Weise modifiziere, wird diese Instanz angelegt, sonst nicht. U. U. könnte ich eine Klasse von der Rohdatenklasse ableiten, aber schien mir hier noch nicht gerechtfertigt.

Also

Code: Alles auswählen

class X:
    def __init__(self):
        self.x = 'irgendwas'
    def modify(self):
        self.y = 'irgendwasanderes'
Wie kann ich jetzt überprüfen, ob X.y existiert oder nicht? Geht das auf direkte Weise?

Gruß,
Christian
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

mawe hat geschrieben:Was aber, wenn ich bei Deiner Methode 2 Objekte erstelle, und eines wieder lösche? Dann ist hasinstance = False, obwohl es noch ein Objekt gibt.
Uuupps! :oops:

Code: Alles auswählen

Traceback (most recent call last):
  File "<stdin>", line 42, in ?
NotGenugNachgedachtException: wach mal auf, Leonidas, bevor du Python-Programme schreibst.
Ja, mawe, dein Weg funktioniert. Jedoch würde es mich interessieren ob es noch eine andere Möglichkeit gibt, die Anzahl der Instanzen einer Klasse auf irgendeinem mysteriösen Weg zu erfahren :)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi Christian!

self.y ist doch eine Instanzvariable, und keine Instanz, oder?
Na jedenfalls

Code: Alles auswählen

>>> class X:
...     def __init__(self):
...             self.x = 'irgendwas'
...     def modify(self):
...             self.y = 'irgendwasanderes'
...
>>> x = X()
>>> x.__dict__
{'x': 'irgendwas'}
>>> x.modify()
>>> x.__dict__
{'y': 'irgendwasanderes', 'x': 'irgendwas'}
>>> x.__dict__.has_key("y")
True
>>>
Gruß, mawe
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

CM hat geschrieben:Und zwar möchte ich das ohne try/except wissen, sondern in einer direkten "Look before you leap"-Manier. (So in etwa wie bei dicts mit dict.has_key().)
Warum kein try/except ??? Oder kommt es nur in Ausnahmefällen vor, das die Instanz existiert und somit fast immer eine Exception ausgelöst wird??? In dem Falle macht es natürlich Sinn mit "look before" zu arbeiten...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

mawe hat geschrieben: self.y ist doch eine Instanzvariable, und keine Instanz, oder?
Na, das meinte ich doch im ersten Post, oder? (siehe Docs) Aber irgendwie ist die Terminologie sowieso nicht ganz klar und wenn ich das falsch begriffen oder übersetzt habe: Asche auf mein Haupt!

Jedenfalls ist Deine Lösung genau das wonach ich gesucht habe und dafür gilt Dir ein großes Dankeschön!

Zu Jens Frage: Weil manchmal LBYL einfach besser ist. Ich finde try/except großartig. Aber in meinem konkreten Fall ist LBYL besser: So wird sich mein Code besser lesen. Natürlich bietet mir die Logik auch andere Auswege an, aber so werde ich näher an der Physik und meiner Datenverarbeitung sein - und das ist was auch zählt. Ganz gemäß dem Python-Zen: "...Readability counts..."

Euch allen vielen Dank.
Gruß,
Christian
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Zum Thema Terminologie ... ich hab das immer so verstanden:

Code: Alles auswählen

class A:
    def __init__(self): 
        self.var = 1

x = A()
print x.var
Ok, A ist eine Klasse :)
x ist ein Objekt bzw. eine Instanz. Darum verwirrt mich auch der Begriff "instance object".
x.var ist ein Objektattribut (ich sag dazu eigentlich immer Objektvariable oder Instanzvariable ... naja, eigentlich sag ich gar nix dazu, ich schreibs einfach hin :)).

Gruß, terminologiegeschädigter mawe
BlackJack

Von wo aus soll denn das vorhandensein geprüft werden? Ich finde es im allgemeinen schlechten Stil, wenn man ausserhalb der __init__() noch Attribute zu einem Objekt hinzufügt.

Was ist denn der Anwendungszweck? Könnte man das Problem mit einem Property lösen?
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hi mawe, bin auch "terminologiegeschädigt". ;-) Aber nun gut, wichtig ist, daß man sich am Ende versteht.

BlackJack, Du hast natürlich recht. Manchmal sehe ich den Wald vor lauter Bäumen nicht. Am besten ist es wohl, wenn ich das instance object oder Objectattribut (oder was auch immer es ist) in __init__ setze und in modify() anders belege und dieses dann abfrage. (Habe ich eingentlich auch schon manches Mal gemacht - ich vergessliche Nudel.)
property() könnte u. U. auch eine Lösung sein, wäre aber wohl auch etwas umständlich. Aber eigentlich sollte ich mir das wieder im Hinterkopf behalten: Ich hatte diese Option schlicht vergessen.

Vielen Dank.

Gruß,
Christian
Antworten