Hallo,
ich hab das Phänomen, dass eine Textersetzung von mehreren Platzhaltern nur in einem Stepp möglich ist - nicht in mehreren - warum?
Beispiel:
Old_Text = "das ist ein {text1} zwei Texte {text2}"
so funktioniert es:
New_Text = Old_Text.format(text1='Versuch', text2='abzubilden')
so funktioniert es nicht:
New_Text = Old_Text.format(text1='Versuch')
New_Text = New_Text.format(text2='abzubilden')
Seltsamerweise schmeißt es schon in der ersten Zeile den Fehler "KeyError: 'text2'"
Habt ihr dafür eine Erklärung?
Gruß Michael
Textersetzung in zwei Steps nicht möglich - warum?
@mimuel: Die Textersetzung schaut nicht welche Platzhalter ersetzt werden können sondern ersetzt alle Platzhalter mit Werten. Und dazu muss halt auch für jeden Platzhalter ein Wert existieren. Wenn es für einen Platzhalter keinen Wert gibt → Ausnahme.
Warum? Warum nicht? Wenn es anders gelöst worden wäre, dann würde irgendwer fragen warum es keine Ausnahme gibt wenn nicht Werte für alle Platzhalter angegeben werden. So wie es jetzt ist, ist es IMHO sauberer und sinnvoller. Wenn man sich bei einem Platzhalter oder beim Namen für einen Wert vertippt, führt das zu einer Ausnahme. Man kann auch einfacher über Ersetzungen nachdenken/diskutieren bei denen der ersetzte Text wieder etwas enthält was wie Platzhalter aussieht. Und für mehre Ersetzungen müsste man auch beim Escapen von Text der wie Platzhalter aussieht mehr Umstände in Kauf nehmen.
Warum? Warum nicht? Wenn es anders gelöst worden wäre, dann würde irgendwer fragen warum es keine Ausnahme gibt wenn nicht Werte für alle Platzhalter angegeben werden. So wie es jetzt ist, ist es IMHO sauberer und sinnvoller. Wenn man sich bei einem Platzhalter oder beim Namen für einen Wert vertippt, führt das zu einer Ausnahme. Man kann auch einfacher über Ersetzungen nachdenken/diskutieren bei denen der ersetzte Text wieder etwas enthält was wie Platzhalter aussieht. Und für mehre Ersetzungen müsste man auch beim Escapen von Text der wie Platzhalter aussieht mehr Umstände in Kauf nehmen.
Hallo,
Danke für Eure Antworten.
In meinem Programm waren die Ersetzungstexte von Bedingungen abhängig.
Jetzt werde ich erst die Erstzungstexte bedingungsabhängig generieren und diese dann alle per format einsetzen.
Hat mich nur verwundert.
Gruß Michael
Danke für Eure Antworten.
In meinem Programm waren die Ersetzungstexte von Bedingungen abhängig.
Jetzt werde ich erst die Erstzungstexte bedingungsabhängig generieren und diese dann alle per format einsetzen.
Hat mich nur verwundert.
Gruß Michael
Man könnte auch mit .replace() arbeiten, falls nicht alle Platzhalter ersetzt werden sollen.
MorgenGrauen: 1 Welt, 8 Rassen, 13 Gilden, >250 Abenteuer, >5000 Waffen & Rüstungen,
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
>7000 NPC, >16000 Räume, >200 freiwillige Programmierer, nur Text, viel Spaß, seit 1992.
- noisefloor
- User
- Beiträge: 3856
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
man kann auch mit der `Template`-Klasse von Strings arbeiten. Die Methode `safe_substitute` kann auch mit fehlenden Werten umgehen.
Gruß, noisefloor
man kann auch mit der `Template`-Klasse von Strings arbeiten. Die Methode `safe_substitute` kann auch mit fehlenden Werten umgehen.
Gruß, noisefloor
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Oder man ersetzt Platzhalter mit Platzhaltern:
Code: Alles auswählen
>>> old = 'bla {t1} blub {t2}'
>>> new = old.format(t1='foo', t2='{t2}')
>>> new
'bla foo blub {t2}'
>>> newest = new.format(t2='bar')
>>> newest
'bla foo blub bar'
In specifications, Murphy's Law supersedes Ohm's.
Und all diese Lösungen haben das Problem, dass in den Parametern keine geschweiften Klammern vorkommen dürfen.
Warum nicht einfach eine Klasse, die sich alles merkt:
Warum nicht einfach eine Klasse, die sich alles merkt:
Code: Alles auswählen
class FormattingString(object):
def __init__(self, format_string, *default_args, **default_kw):
self.format_string = format_string
self.default_args = default_args
self.default_kw = default_kw
self.args = []
self.kw = {}
def __setitem__(self, key, value):
self.kw[key] = value
def append(self, value):
self.args.append(value)
def __str__(self):
args = self.args + list(self.default_args[len(self.args):])
kw = dict(self.default_kw, **self.kw)
return self.format_string.format(*args, **kw)
template = FormattingString("das ist ein {text1} zwei Texte {text2}")
template['text1'] = "Versuch"
template['text2'] = "abzubilden"
print(template)
- pillmuncher
- User
- Beiträge: 1484
- Registriert: Samstag 21. März 2009, 22:59
- Wohnort: Pfaffenwinkel
Warum nicht einfach mit Currying?
Code: Alles auswählen
>>> def curry(f=None, *, params=1):
... def curried(f, *old_args, **old_kwargs):
... def fun(*new_args, **new_kwargs):
... args = old_args + new_args
... kwargs = {}
... kwargs.update(old_kwargs)
... kwargs.update(new_kwargs)
... if len(args) + len(kwargs) < params:
... return curried(f, *args, **kwargs)
... else:
... return f(*args, **kwargs)
... return fun
... if f is None:
... return curried
... else:
... return curried(f)
...
>>> old = 'bla {t1} blub {t2}'
>>> format_old = curry(params=2)(old.format)
>>> format_tmp = format_old(t1='foo')
>>> format_tmp(t2='bar')
'bla foo blub bar'
In specifications, Murphy's Law supersedes Ohm's.