Если у меня есть следующий код Python:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
Жалуется
NameError: global name 'bar' is not defined
Как я могу получить доступ к классу / статической переменной bar
внутри метода bah
?
python
oop
static-variables
Росс Роджерс
источник
источник
Ответы:
Вместо
bar
использованияself.bar
илиFoo.bar
. Назначение дляFoo.bar
создаст статическую переменную, а присвоениеself.bar
создаст переменную экземпляра.источник
Определите метод класса:
Теперь, если
bah()
должен быть метод экземпляра (т.е. иметь доступ к себе), вы все равно можете напрямую получить доступ к переменной класса.источник
Как и во всех хороших примерах, вы упростили то, что вы на самом деле пытаетесь сделать. Это хорошо, но стоит отметить, что python обладает большой гибкостью, когда речь идет о переменных класса и экземпляра. То же самое можно сказать и о методах. Для хорошего списка возможностей я рекомендую прочитать введение в классы нового стиля Михаэля Фетша , особенно разделы со 2 по 6.
Одна вещь, которую нужно запомнить, чтобы начать работу, это то, что python - это не Java. Больше, чем просто клише. В Java весь класс компилируется, что делает разрешение пространства имен по-настоящему простым: любые переменные, объявленные вне метода (где угодно), являются переменными экземпляра (или, если они статические, класса) и неявно доступны внутри методов.
В Python главное правило заключается в том, что есть три пространства имен, которые ищутся по порядку для переменных:
{begin pedagogy}
Есть ограниченные исключения из этого. Главное, что приходит мне в голову, это то, что при загрузке определения класса определение класса является его собственным неявным пространством имен. Но это длится только до тех пор, пока модуль загружается, и полностью игнорируется в методе. Таким образом:
но:
{end pedagogy}
В конце концов, что нужно помнить, что вы действительно имеете доступ к любой из переменных , которые вы хотите получить доступ, но , вероятно , не неявно. Если ваши цели просты и понятны, то, вероятно, будет достаточно перейти на Foo.bar или self.bar. Если ваш пример усложняется, или вы хотите заняться такими причудливыми вещами, как наследование (вы можете наследовать статические методы / методы класса!), Или идея ссылки на имя вашего класса внутри самого класса кажется вам неправильной, проверьте вступление я связал.
источник
источник
источник