В Python, как я могу получить доступ к «статическим» переменным класса внутри методов класса - PullRequest
128 голосов
/ 02 апреля 2009

Если у меня есть следующий код Python:

class Foo(object):
    bar = 1

    def bah(self):
        print(bar)

f = Foo()
f.bah()

жалуется

NameError: global name 'bar' is not defined

Как получить доступ к классу / статической переменной bar в методе bah?

Ответы [ 5 ]

131 голосов
/ 02 апреля 2009

Вместо bar используйте self.bar или Foo.bar. Присвоение Foo.bar создаст статическую переменную, а присвоение self.bar создаст переменную экземпляра.

67 голосов
/ 02 апреля 2009

Определить метод класса:

class Foo(object):
    bar = 1
    @classmethod
    def bah(cls):    
        print cls.bar

Теперь, если bah() должен быть методом экземпляра (т.е. иметь доступ к себе), вы все равно можете напрямую обращаться к переменной класса.

class Foo(object):
    bar = 1
    def bah(self):    
        print self.bar
11 голосов
/ 02 апреля 2009

Как и во всех хороших примерах, вы упростили то, что вы на самом деле пытаетесь сделать. Это хорошо, но стоит отметить, что python обладает гибкостью lot , когда речь идет о переменных класса и экземпляра. То же самое можно сказать и о методах. Для хорошего списка возможностей я рекомендую прочитать введение в классы нового стиля Михаэля Феча , особенно разделы со 2 по 6.

Одна вещь, которую нужно запомнить, чтобы начать работу, это то, что python - это не Java. Больше, чем просто клише. В java весь класс компилируется, что делает разрешение пространства имен по-настоящему простым: любые переменные, объявленные вне метода (где угодно), являются переменными экземпляра (или, если они статические, класса) и неявно доступны внутри методов.

В Python главное правило состоит в том, что есть три пространства имен, по которым ищутся переменные:

  1. Функция / метод
  2. Текущий модуль
  3. 1018 * Встроенные команды *

{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}

В конце концов, нужно помнить, что у вас do есть доступ к любой из переменных, к которым вы хотите получить доступ, но, вероятно, неявно. Если ваши цели просты и понятны, то, вероятно, будет достаточно перейти на Foo.bar или self.bar. Если ваш пример усложняется, или вы хотите сделать такие причудливые вещи, как наследование (вы можете наследовать статические методы / методы класса!), Или идея ссылки на имя вашего класса внутри самого класса кажется вам неправильной, проверьте вступление я связал.

9 голосов
/ 10 января 2017
class Foo(object):
     bar = 1
     def bah(self):
         print Foo.bar

f = Foo() 
f.bah()
0 голосов
/ 02 ноября 2018
class Foo(object) :

          bar = 1

          def bah(object_reference) :

                 object_reference.var=Foo.bar

                 return object_reference.var

f = Foo() 

print 'var=', f.bah()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...