Як і у всіх хороших прикладах, ви спростили те, що насправді намагаєтесь зробити. Це добре, але варто зазначити, що python має велику гнучкість, коли мова йде про змінні класу проти екземплярів. Те саме можна сказати і про методи. Для гарного переліку можливостей рекомендую ознайомитись із введенням нового класу Майкла Фотча , особливо розділи 2 по 6.
Одне, що потребує великої праці, щоб пам’ятати, коли почати, це те, що пітон не є Java. Більше, ніж просто кліше. У java складається цілий клас, що робить роздільну здатність простору імен справжньою: будь-які змінні, оголошені поза методом (де завгодно), є змінними екземпляра (або, якщо статичні, класові) і явно доступні в межах методів.
Для python головним правилом є те, що є три простори імен, які шукаються в порядку змінних:
- Функція / метод
- Поточний модуль
- Вбудовані
{begin pedagogy}
Винятки з цього обмежені. Головне, що мені трапляється, - це те, що коли завантажується визначення класу, визначення класу є власним неявним простором імен. Але це триває лише до тих пір, поки модуль завантажується, і повністю його обходить, коли в межах методу. Таким чином:
>>> class A(object):
foo = 'foo'
bar = foo
>>> A.foo
'foo'
>>> A.bar
'foo'
але:
>>> class B(object):
foo = 'foo'
def get_foo():
return foo
bar = get_foo()
Traceback (most recent call last):
File "<pyshell#11>", line 1, in <module>
class B(object):
File "<pyshell#11>", line 5, in B
bar = get_foo()
File "<pyshell#11>", line 4, in get_foo
return foo
NameError: global name 'foo' is not defined
{end pedagogy}
Зрештою, що потрібно пам'ятати, що ви дійсно маєте доступ до будь-якої із змінних , які ви хочете отримати доступ, але , ймовірно , НЕ неявно. Якщо ваші цілі прості і прості, то, ймовірно, буде достатньо для Foo.bar або self.bar. Якщо ваш приклад стає складнішим, або ви хочете робити такі фантазійні речі, як спадкування (ви можете успадкувати статичні / класичні методи!), Або ідея посилатися на ім’я вашого класу в межах самого класу здається вам неправильною, перевірте вступ я пов’язав.