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

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

class Foo(object):
    bar = 1

    def bah(self):
        print(bar)

f = Foo()
f.bah()

Жалуется

NameError: global name 'bar' is not defined

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

Ответ 1

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

Ответ 2

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

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

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

class Foo(object):
    bar = 1
    def bah(self):    
        print self.bar

Ответ 3

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

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

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

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

{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. Если ваш пример усложняется, или вы хотите сделать такие причудливые вещи, как наследование (вы можете наследовать статические/методы класса!), Или идея ссылки на имя вашего класса внутри самого класса кажется вам неправильной, проверьте вступление я связал.

Ответ 4

class Foo(object):
     bar = 1
     def bah(self):
         print Foo.bar

f = Foo() 
f.bah()

Ответ 5

class Foo(object) :

          bar = 1

          def bah(object_reference) :

                 object_reference.var=Foo.bar

                 return object_reference.var

f = Foo() 

print 'var=', f.bah()