Seite 1 von 1

Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 10:23
von mimuel
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

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 10:28
von Sirius3
@mimuel: dafür braucht man keine Erklärung. So funktioniert `.format` eben. Wo ist Dein Problem damit?

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 10:32
von BlackJack
@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.

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 11:21
von mimuel
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

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 13:07
von Kebap
Man könnte auch mit .replace() arbeiten, falls nicht alle Platzhalter ersetzt werden sollen.

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 13:12
von noisefloor
Hallo,

man kann auch mit der `Template`-Klasse von Strings arbeiten. Die Methode `safe_substitute` kann auch mit fehlenden Werten umgehen.

Gruß, noisefloor

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 13:41
von pillmuncher
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'

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 15:18
von snafu
Einfach die geschweiften Klammern, bei denen im ersten Schritt keine Ersetzung gemacht werden soll, doppelt schreiben.

Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 16:03
von Sirius3
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:

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)


Re: Textersetzung in zwei Steps nicht möglich - warum?

Verfasst: Mittwoch 4. Januar 2017, 17:19
von pillmuncher
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'