Nie wiem, dlaczego tak wiele komentarzy powyżej zawiera poprawną odpowiedź i nikt nie odważył się napisać odpowiedzi, więc zrobię to tutaj.
class ThisWorksNow(object):
def outer(self):
acc = []
def inner(msg):
acc.append(msg)
inner("Why doesn't")
inner(" this work?")
print "".join(acc)
ThisWorksNow().outer()
Jaka jest różnica?
Przypisywanie nazwy do obiektu znajdującego się w zamknięciu nie działa w języku Python 2.x, ponieważ brakuje słowa kluczowego Py3 nonlocal
, dlatego musimy znaleźć obejście problemu.
Jeśli musimy zachować stałą wiązania nazwa-obiekt, musimy zmienić coś innego. W tym przypadku jest to obiekt, do którego dodawana jest zawartość do dodania.
Linia print
nie jest bardzo elegancka; może bardziej odpowiedni będzie obiekt, który drukuje jego zawartość połączoną.
class StringBuilder(list): # class name stolen from Java
def __str__(self):
"""this makes the object printable in a way which represents the concatenated string"""
return "".join(self)
@property
def string(self):
"""this gives us a property which represents the concatenated string"""
return "".join(self)
# use whatever suits you better, one or both
Z tego, co możemy zrobić, aby:
class ThisWorksNow(object):
def outer(self):
acc = StringBuilder()
def inner(msg):
acc.append(msg)
inner("Why doesn't")
inner(" this work?")
print acc
print acc.string # depending on what you take above
ThisWorksNow().outer()
Edit (dołącz): Dlaczego global
nie działa?
Możemy to osiągnąć również z global
, z 2 wadami.
acc
musiałby być globalny na obu miejscach używamy go
class WhyDoesntThisWork(object):
def outer(self):
global acc
acc = ''
def inner(msg):
global acc
acc = acc + msg
Niniejszym "lift" oba acc
zdarzenia do poziomu "global
".
acc
może być modyfikowany z zewnątrz.
Jeśli wykonamy global acc
gdzie indziej, lub używamy acc
na poziomie modułu, nasz proces może zostać zmodyfikowany. Należy tego unikać.
'global' nie działa z zamknięciami. Zamiast tego potrzebujesz 'nonlocal' z Pythona 3. –
Zamiast tego użyj zmiennego (brak globalnego słowa kluczowego); 'acc = []', 'acc.append', itp. –
W porządku, więc używa się zmiennego (' acc = [] '). Czy możesz wyjaśnić, dlaczego to ma znaczenie ... po prostu dla ciekawostek? – sholsapp