Seite 1 von 1

Design, Garbage

Verfasst: Samstag 25. Oktober 2008, 10:14
von __marcus__

Code: Alles auswählen

class Test():
	def __call__(self):
		x = 'foo' * 5000000000
		y = 'bar'
		z = 15
		return z
				
z = Test()()
Wenn ich eine Klasse habe, die für mich eine Aufgabe erledigt und am Ende interessieren mich nur zwei Variablen in dieser Klasse, brauche ich ja im Grunde genommen keine Instanz dieser Klasse.

Ist sowas wie das Beispiel oben dann eine gute Idee? Ich bin mir halt nicht sicher, weil wenn es so eine gute Idee wäre, dürfte ja wohl auch __init__ etwas anderes als None zurückgeben und es wäre überflüssig dieses Hindernis auf diese Weise zu umgehen.

Verfasst: Samstag 25. Oktober 2008, 10:17
von Leonidas
Du hast doch auch hier eine Instanz der Klasse, aber du simulierst eine Funktion auf umständliche Art und Weise, keine Ahnung was du genau damit bezwecken willst.

Re: Design, Garbage

Verfasst: Samstag 25. Oktober 2008, 10:32
von sma
__marcus__ hat geschrieben:Ist sowas wie das Beispiel oben dann eine gute Idee?
Nein in zweierlei Hinsicht. Erstens ist es in aller Regel müßig, einzelne Bytes sparen zu wollen (insbesondere wo du versucht, einen 15 GB großen String anzulegen! Da spielt dein Test-Exemplar keine Rolle) und auch nur eine Sekunde über den Speicherverbrauch eines einzelnen Exemplars der Klasse nachdenken zu wollen und zweitens braucht du einfach eine Funktion

Code: Alles auswählen

def wtf(): return 15
Stefan

Re: Design, Garbage

Verfasst: Samstag 25. Oktober 2008, 10:43
von farid
__marcus__ hat geschrieben:Ist sowas wie das Beispiel oben dann eine gute Idee?
Funktionsobjekte (callables) sind nur dann sinnvoll, wenn man den Zustand manipuliert:

Code: Alles auswählen

class Counter(object):
    def __init__(self, init=0):
        self.value = init

    def __call__(self):
        self.value = self.value + 1
        return self.value
Jetzt kannst Du einen Zaehler simulieren:

Code: Alles auswählen

>>> myCounter = Counter(0)
>>> myCounter()
1
>>> myCounter()
2

>>> myOtherCounter = Counter(10)
>>> myOtherCounter()
11
>>> myCounter()
3

Verfasst: Samstag 25. Oktober 2008, 10:45
von __marcus__
Ach so ja, gut, dann mache ich das nicht mit __call__ sondern nehme einfach eine normale Funktion. Danke. (Es ging mir halt darum, dass in der Klasse sowieso viel Müll anfällt und ich wissen wollte, wie ich den am Besten loswerde ohne in der Klasse einzelne Variablen zu löschen.)

Verfasst: Samstag 25. Oktober 2008, 11:09
von BlackJack
@__marcus__: Wo fällt da viel Müll an, den man "löschen" müsste? Du bindest ja nichts an das Exemplar. Der Müll fällt nicht "in der Klasse" an, sondern wird in der Methode an lokale Namen gebunden. Da besteht kein Unterschied zu einer Funktion.

Verfasst: Samstag 25. Oktober 2008, 12:04
von __marcus__
Nein, ursprüglich war es so,

data = Test(filename)

und dann habe ich auf

data.z

zugegriffen.

Aber jetzt ist alles gut und ich werde auch nie wieder vor dem Frühstück denken, dass ich vor schwerwiegenden Problemen stehe.

Re: Design, Garbage

Verfasst: Samstag 25. Oktober 2008, 16:32
von birkenfeld
farid hat geschrieben:
__marcus__ hat geschrieben:Ist sowas wie das Beispiel oben dann eine gute Idee?
Funktionsobjekte (callables) sind nur dann sinnvoll, wenn man den Zustand manipuliert:

Code: Alles auswählen

class Counter(object):
    def __init__(self, init=0):
        self.value = init

    def __call__(self):
        self.value = self.value + 1
        return self.value
Jetzt kannst Du einen Zaehler simulieren:

Code: Alles auswählen

>>> myCounter = Counter(0)
>>> myCounter()
1
>>> myCounter()
2

>>> myOtherCounter = Counter(10)
>>> myOtherCounter()
11
>>> myCounter()
3
Wobei man sich gerade in solchen Fällen die Klasse sparen und einen Generator verwenden kann.

Verfasst: Samstag 25. Oktober 2008, 17:13
von BlackJack
Und in diesem speziellen Fall…

Code: Alles auswählen

In [36]: import itertools

In [37]: my_counter = itertools.count(10).next

In [38]: my_counter()
Out[38]: 10

In [39]: my_counter()
Out[39]: 11

In [40]: my_counter()
Out[40]: 12
:-)