Ответ 1
Вместо bar
используйте self.bar
или Foo.bar
. Присвоение Foo.bar
создаст статическую переменную, и присвоение self.bar
создаст переменную экземпляра.
Если у меня есть следующий код Python:
class Foo(object):
bar = 1
def bah(self):
print(bar)
f = Foo()
f.bah()
Жалуется
NameError: global name 'bar' is not defined
Как я могу получить доступ к классу/статической переменной bar
в методе bah
?
Вместо bar
используйте self.bar
или Foo.bar
. Присвоение Foo.bar
создаст статическую переменную, и присвоение self.bar
создаст переменную экземпляра.
Определить метод класса:
class Foo(object):
bar = 1
@classmethod
def bah(cls):
print cls.bar
Теперь, если bah()
должен быть методом экземпляра (т.е. иметь доступ к себе), вы все равно можете получить доступ к переменной класса.
class Foo(object):
bar = 1
def bah(self):
print self.bar
Как и во всех хороших примерах, вы упростили то, что вы на самом деле пытаетесь сделать. Это хорошо, но стоит отметить, что python обладает большой гибкостью, когда речь идет о переменных класса и экземпляра. То же самое можно сказать и о методах. Для хорошего списка возможностей, я рекомендую прочитать введение в классы Михаэля Фетша, особенно разделы со 2 по 6.
Одна вещь, которую нужно запомнить, чтобы начать работу, это то, что python - это не 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. Если ваш пример усложняется, или вы хотите сделать такие причудливые вещи, как наследование (вы можете наследовать статические/методы класса!), Или идея ссылки на имя вашего класса внутри самого класса кажется вам неправильной, проверьте вступление я связал.
class Foo(object):
bar = 1
def bah(self):
print Foo.bar
f = Foo()
f.bah()
class Foo(object) :
bar = 1
def bah(object_reference) :
object_reference.var=Foo.bar
return object_reference.var
f = Foo()
print 'var=', f.bah()