Seite 1 von 1

Abfragen ob Klasseninstanz existiert

Verfasst: Freitag 12. August 2005, 07:25
von CM
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

Verfasst: Freitag 12. August 2005, 08:04
von mawe
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

Verfasst: Freitag 12. August 2005, 10:42
von Leonidas
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.

Verfasst: Freitag 12. August 2005, 10:47
von mawe
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

Verfasst: Freitag 12. August 2005, 10:52
von CM
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

Verfasst: Freitag 12. August 2005, 10:53
von Leonidas
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 :)

Verfasst: Freitag 12. August 2005, 11:03
von mawe
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

Re: Abfragen ob Klasseninstanz existiert

Verfasst: Freitag 12. August 2005, 11:14
von jens
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...

Verfasst: Freitag 12. August 2005, 14:41
von CM
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

Verfasst: Freitag 12. August 2005, 15:09
von mawe
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

Verfasst: Sonntag 14. August 2005, 00:24
von 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?

Verfasst: Montag 15. August 2005, 10:59
von CM
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