If I do not use global M in function
test, It would issue error.
This statement of yours is simply not true!!!
>>> M = []
>>> s = "abc"
>>>
>>> def test():
... M.append(s)
...
>>> M
[]
>>> test()
>>> M
['abc']
I think you're confusing two utterly and completely different concepts:
binding a barename -- usually by assignment (i.e. =
), but also possibly
by a few other statements (def
, &c)
calling a method (such as append
) which "may" happen to mutate the object
(only if that object is mutable and the method is a mutator of course, but that
does apply when the object is a list and the method is append
)
I'm not sure why people can confuse the two poles-apart concepts, but, they surely can. Maybe it's the fact that some non-plain-vanilla "kinds" of assignment are actually calling a (special) method "behind the curtains", e.g., assignment to qualified names (a.b=c
is actually calling type(a).__setitem__(a, b)
, so, calling a method, not rebinding any barename) and augmented assignment (a+=b
is actually doing a = type(a).__iadd__(a, b)
, so, both calling a method and rebinding a barename).
You need global
(alas) if and only if you're doing "1": rebinding a barename (including rebinding it by augmented assignment but not including any other special case). Eschew global
unless it's really indispensable (and many would say it's never truly indispensable... just "apparently kind of handy" in some cases;-).