It has nothing to do with static vs. dynamic. There's no reason that being an early-binding language that a string has to be iterable itself, and the proposal to change this was only rejected as it broke too many things[1] and couldn't be automatically fixed.
Point in the GP's favor: Fixing it would definitely not be a problem with an early-binding language! In fact, the nigh-impossibility of automated refactoring puts lie to the notion that late-binding languages are more "agile."
It's a design flaw, in the same way Python 2's allowing comparisons between different types was a flaw, e.g. "a" < 3 succeeds. Python 3 now, correctly, throws a TypeError because there's no sensible ordering between the two things.
(While I'm griping: Another design flaw is conflating iterables and iterators, which makes generators almost useless. Say a generator is pass to a function expecting an iterable. If the function uses it twice, the second time it silently returns nothing!)
> This isn't what Python would do, if the variable was undefined Python will throw an error
I think GP must have assigned to the name, in which case Python will create a lexically bound name.
Python's rules for naming can make perfect sense or be quite surprising:
try:
x = four()
except Thing:
x = 5
print(x) # 4 or 5
for a in [1, 2, 3]:
pass
print(a) # 3 ?!
[1]:
https://mail.python.org/pipermail/python-3000/2006-April/000...