@Leonidas:
Das
Code: Alles auswählen
print kellerspeicher.alphabet
Code: Alles auswählen
print kellerspeicher.kalphabet
Aber das mit mutable object versteh ich noch nicht so ganz...
Meinst du meine Forensignatur?
MfG Jonas
Code: Alles auswählen
print kellerspeicher.alphabet
Code: Alles auswählen
print kellerspeicher.kalphabet
Code: Alles auswählen
In [87]: def foo(bar=[]):
....: return bar
....:
In [88]: a = foo()
In [89]: a.append('spam')
In [90]: foo()
Out[90]: ['spam']
Nein, ich meine die Funktionssignatur von ``__init__``.jonas hat geschrieben:Aber das mit mutable object versteh ich noch nicht so ganz...
Meinst du meine Forensignatur?
Code: Alles auswählen
>>> class K(object):
... def __init__(self, args=[]):
... args.append(7)
... self.args = args
...
>>> k1 = K([1, 2, 3])
>>> k2 = K()
>>> k1.args
[1, 2, 3, 7]
>>> k2.args
[7]
>>> k3 = K()
>>> k3.args
[7, 7]
Code: Alles auswählen
def irgendeinefunktion ():
try:
## tuEtwas...
except :
print """Hallo es gab irgendeinen Error aber
machen Sie sich mal keine Sorgen..."""
Ist so eine spezialisierte Klasse z.B. Frog <=> Tkinter ?str1442 hat geschrieben:[...]Beispielsweise ist ein solcher Einsatz denkbar wenn du eine Klasse erstellst, die eine API implementiert (add_thing, remove_thing, do_somethign_important ...), und dann eine spezialisiertere Klasse erstellst, die von dieser abgeleitet ist.[...]
Code: Alles auswählen
class AbstractCls(object):
def add(self):
pass
def request(self):
pass
class Cls(AbstractCls):
def add(self):
# Wichtiger Code
def _do_sth_for_add(self):
# Mach irgendwas und nutze Instanzvariablen dazu.
Ja, natürlich, aber funktionen die implementiert werden sollten, sollten Ausnahmen werfen. Sonst kann man sie auch einfach nicht implementieren und sich wundern warum dann an seltsamen Stellen ``None`` auftaucht. Ich finde es ähnlich wie du auch wenig sinnvoll wenn man in Interfaces nicht auch teile der Implementation haben kann. In Scalas Traits ist das anders, dort kann man in den Traits schon eine Implementation haben aber wenn man abstrakte Methoden des Traits nicht implementiert, wird es nicht kompilieren. Sowas kann man eben mit normalen Klassen und NotImplementedError auch haben; allerdings zur Laufzeit.str1442 hat geschrieben:Die einzelnen Methoden müssen ja nicht einfach durchgehen. In Java ist das afaik ja zwingend, das man eine interface Methode nicht weiter spezifieren kann. Aber wenn 5 verschiedene Parser beispielsweise sowieso immer ~3 Methoden haben, die komplett gleich sind, unterscheidet sich das nicht vom normalen Einsatzzweck von Vererbung.
Wieso? Statt ``None`` wird man dann ``NotImplemented`` im Programm umherfliegen haben und man darf dann den Debugger anwerfen um festzustellen welche Funktion nicht implementiert wurde. Da finde ich Ausnahmen wesentlich besser, weil eben der letzte Frame im Traceback der Funktion entspricht, die man überschreiben muss.str1442 hat geschrieben:Statt dem NotImplementedError gibts auch das NotImplemented Singleton. Wäre wohl besser, das zurückzugeben.
Wie gesagt, ich meine nur irgendwo mal was diesbezüglich gelesen zu haben. Ansonsten ist eine Ausnahme wohl besser geeignet, ja. Welchen Zweck hat aber NotImplemented, wenn man es sowieso nie zurückgeben sollte? Gibt ja dann eigentlich keinen Einsatzzweck mehr dafür.Wieso? Statt ``None`` wird man dann ``NotImplemented`` im Programm umherfliegen haben und man darf dann den Debugger anwerfen um festzustellen welche Funktion nicht implementiert wurde. Da finde ich Ausnahmen wesentlich besser, weil eben der letzte Frame im Traceback der Funktion entspricht, die man überschreiben muss.
Ich muss gestehen dass ich NotImplemented auch noch nie verwendet habe, aber die Dokumetation sagt schon wozu es gut ist:str1442 hat geschrieben:Welchen Zweck hat aber NotImplemented, wenn man es sowieso nie zurückgeben sollte? Gibt ja dann eigentlich keinen Einsatzzweck mehr dafür.
Ist also für ganz andere Sachen gedacht.Python Dokumentation hat geschrieben:Numeric methods and rich comparison methods may return this value if they do not implement the operation for the operands provided. (The interpreter will then try the reflected operation, or some other fallback, depending on the operator.)
Insofern scheint das ja geklärt zu seinThis exception is derived from RuntimeError. In user defined base classes, abstract methods should raise this exception when they require derived classes to override the method.
Das wäre eine Möglichkeit, zB soxdhwde hat geschrieben: theoretisch müsst ich ja nur noch ne raw_input methode machen für die werte und dann die methode pop and eval aufrufen oder? habt ihr noch verbesserungs vorschläge!
Code: Alles auswählen
from math import *
class CalcUPN(object):
DIGITS = '0123456789'
SEPARATOR = ' '
def __init__(self):
self.result = 0.000
self.clearHistory()
def __repr__(self):
return "%.3f" % self.result
def __operation(self,op):
op1 = str(self.__stack.pop())
try:
op2 = str(self.__stack.pop())
except IndexError:
op = op + '('
op1 = op1 + ')'
op2 = ''
return eval(op2 + op + op1)
def calc(self,user_input = None):
self.__stack = []
if not user_input:
user_input = raw_input("calc: ").split(self.SEPARATOR)
else: user_input = user_input.split(self.SEPARATOR)
for data in user_input:
self.__stack.append(float(data)) if data[0] in self.DIGITS else self.__stack.append(self.__operation(data))
self.result = self.__stack[0]
self.history.append(self.result)
return self.result
def clearHistory(self):
self.history = []
>>> calc1 = CalcUPN()
>>> calc1.calc()
calc: 1 2 + 3 *
9.0
>>> calc1.calc()
calc: 1 2 + 3 4 + * 5 + 6 7 - -
27.0
>>> calc1.calc('4 3 - 2 /')
0.5
>>> calc1.calc()
calc: 1 2 + 3 * sin
0.41211848524175659
>>> calc1.calc()
calc: 1 2 + 3 * radians sin
0.15643446503974723
>>> calc1.result
0.15643446503974723
>>> calc1.history
[9.0, 27.0, 0.5, 0.41211848524175659, 0.15643446503974723]
>>> calc1
0.156
>>>
Code: Alles auswählen
import operator
OPERATORS = {
'+': operator.add,
'-': operator.sub,
'*': operator.mul,
'**': operator.pow,
'//': operator.truediv,
'%': operator.mod
}
class Stack(list):
def __init__(self, *args):
for arg in args:
self.append(arg)
def append(self, element):
if element in OPERATORS:
if len(self) < 2:
raise ValueError('Not enough operands on the stack')
list.append(self, OPERATORS[element](*(arg for arg in self.pop())))
elif str(element).isdigit():
list.append(self, element)
else:
raise TypeError('{0} is not an operator or digit'.format(element))
def pop(self):
return [list.pop(self) for dummy in xrange(2)]
Code: Alles auswählen
list.append(self, OPERATORS[element](*(arg for arg in self.pop())))