Попробую на пальцах.
my_str_1 = "1: outside of func"
my_str_2 = "2: outside of func"
определили две переменных в глобальном неймспейсе
def func():
my_str_1 = "1: inside the func"
my_str_2 = "2: inside the func"
определили две переменных в локальном для функции неймспейсе, имена перекрывают глобальный
class C:
print(my_str_1)
print(my_str_2)
класс будет создаваться в момент вызова функции и распечатает две переменных. поиск имен: локальный неймспейс, потом глобальный, встроенные имена (подробнее лучче почитать в книжках,
http://www.rsdn.ru/article/python/python_name_resolving.xml например)
my_str_1 = "1: inside the class"
в момент выполнения в неймспейсе класса будет создана такая переменная.
причем интрепретатор запомнил, что переменная будет использоваться как локальная.
нам нужно распечатать my_str_1 - на локальном неймспейсе её нет (определяется позднее), ищем в глобалном, находим печатаем.
Тонкость в том, что порядок поиска имен не равнозначен порядку вложенности кода. Что и приводит к недоумению.