Re: [Python-de] Neue Instance mit gleichem Typ über eine Variable?
Diez B. Roggisch wrote:
On May 25, 2013, at 12:23 PM, Michael Ströder <michael@stroeder.com> wrote:
Besser wäre
def foo(var = None): var = var or {} [..]
Dann wird nämlich jedes Mal eine neue Dictionary-Instanz erzeugt, falls nur foo() aufgerufen wird.
Und noch besser wäre
var = {} if var is None else var
seit Python 2.5.
Nun, man hat leider nicht immer das Privileg eine einigermaßen aktuelle Python-Version zur Verfügung zu haben (z.B. RHEL5).
Denn dieses Gefummel mit or und and statt dem ternaeren if führt ebenfalls zu seiner ganz eigenen Klasse von Fehlern.
Welche Fehler sind das genau? Ciao, Michael.
Michael Ströder wrote:
Diez B. Roggisch wrote:
On May 25, 2013, at 12:23 PM, Michael Ströder <michael@stroeder.com> wrote:
Besser wäre
def foo(var = None): var = var or {} [..]
Dann wird nämlich jedes Mal eine neue Dictionary-Instanz erzeugt, falls nur foo() aufgerufen wird.
Und noch besser wäre
var = {} if var is None else var
seit Python 2.5.
Nun, man hat leider nicht immer das Privileg eine einigermaßen aktuelle Python-Version zur Verfügung zu haben (z.B. RHEL5).
Meiner Meinung nach ist sowieso if var is None: var = {} /noch/ besser ;)
Denn dieses Gefummel mit or und and statt dem ternaeren if führt ebenfalls zu seiner ganz eigenen Klasse von Fehlern.
Welche Fehler sind das genau?
Zum Beispiel "vergisst" deine Variante von foo() den Typ des Arguments, wenn es sich um ein leeres Dictionary handelt:
def foo(var=None): ... var = var or {} ... var["result"] = type(var)() ... return var ... assert type(foo({1: 2})["result"]) is dict assert type(foo({})["result"]) is dict assert type(foo(OrderedDict([(1,2)]))["result"]) is OrderedDict assert type(foo(OrderedDict([]))["result"]) is OrderedDict Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError
Meiner Meinung nach ist sowieso
if var is None: var = {}
/noch/ besser ;)
Stimmt - mache ich selbst eigentlich auch meistens so, mir ging's aber auch um den generellen Fall, wo ja gerne mit "<cond> and <trueval> or <falseval>" rumgehampelt wird.
Zum Beispiel "vergisst" deine Variante von foo() den Typ des Arguments, wenn es sich um ein leeres Dictionary handelt:
def foo(var=None): ... var = var or {} ... var["result"] = type(var)() ... return var ... assert type(foo({1: 2})["result"]) is dict assert type(foo({})["result"]) is dict assert type(foo(OrderedDict([(1,2)]))["result"]) is OrderedDict assert type(foo(OrderedDict([]))["result"]) is OrderedDict Traceback (most recent call last): File "<stdin>", line 1, in <module> AssertionError
Und natürlich noch besser als mein Beispiel ;) Diez
On May 26, 2013, at 8:57 AM, Michael Ströder <michael@stroeder.com> wrote:
Diez B. Roggisch wrote:
On May 25, 2013, at 12:23 PM, Michael Ströder <michael@stroeder.com> wrote:
Besser wäre
def foo(var = None): var = var or {} [..]
Dann wird nämlich jedes Mal eine neue Dictionary-Instanz erzeugt, falls nur foo() aufgerufen wird.
Und noch besser wäre
var = {} if var is None else var
seit Python 2.5.
Nun, man hat leider nicht immer das Privileg eine einigermaßen aktuelle Python-Version zur Verfügung zu haben (z.B. RHEL5).
Deswegen kann man trotzdem zeigen, wie der Stand der Technik ist (und das seit fast 7 Jahren). Workarounds für besondere Umstände sind davon ja nicht betroffen.
Denn dieses Gefummel mit or und and statt dem ternaeren if führt ebenfalls zu seiner ganz eigenen Klasse von Fehlern.
Welche Fehler sind das genau?
In dem Moment, wo deine Erwartungshaltung bool(o) == False auch von an var übergebenen Objekten erfüllt wird.
def foo(var=None): ... var = var or {} ... print var, type(var) ... foo() {} <type 'dict'> foo("") {} <type 'dict'> class mydict(dict): ... def __nonzero__(self): ... return False … foo(mydict()) {} <type 'dict'>
Das mydict ist natürlich hier etwas konstruiert, aber durchaus realistisch. Diez
participants (3)
-
Diez B. Roggisch
-
Michael Ströder
-
Peter Otten