NameError: имя x не определено [дубликат]

Не повредит. Вы можете даже вызвать функцию с меньшим количеством параметров, чем требуется, если код функции в порядке с несколькими неопределенными значениями.

107
задан Ross Rogers 27 May 2017 в 18:19
поделиться

4 ответа

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

105
ответ дан Pavel Strakhov 15 August 2018 в 15:02
поделиться
  • 1
    Foo.bar будет работать, но self.bar создает переменную экземпляра, а не статическую. – bedwyr 1 April 2009 в 22:55
  • 2
    bedwyr, "print self.bar" не создаст никаких переменных экземпляра (хотя присваивание self.bar будет). – Constantin 1 April 2009 в 23:14
  • 3
    @Constantin - Я этого не понимал, это интересное различие. Спасибо за исправление :-) – bedwyr 3 April 2009 в 02:14
  • 4
    Но если вы не собираетесь там быть иваром, его яснее использовать Foo.classmember. – mk12 13 September 2009 в 21:58
  • 5
    при использовании статических переменных рекомендуется прочитать getchas отсюда: stackoverflow.com/questions/68645/… . @ Константин дает одну из многих ошибок. – Trevor Boyd Smith 21 March 2017 в 17:27
class Foo(object):
     bar = 1
     def bah(self):
         print Foo.bar

f = Foo() 
f.bah()
5
ответ дан Allan Mwesigwa 15 August 2018 в 15:02
поделиться

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

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

С помощью python главное правило состоит в том, что для переменных есть три пространства имен:

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

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

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

10
ответ дан florisla 15 August 2018 в 15:02
поделиться
  • 1
    IIRC, есть технически 3 (+) пространства имен, которые искали - function-local, module / global и builtins. Вложенные области означают, что можно искать несколько локальных областей, но это один из исключительных случаев. (...) – Jeff Shannon 2 April 2009 в 09:52
  • 2
    Кроме того, я был бы осторожен, говоря «основной модуль», так как это поиск модуля, который был найден, а не модуль main ... И поиск атрибута из экземпляра ref - это другое дело , но этот ответ объясняет почему вам нужен экземпляр / класс ref. – Jeff Shannon 2 April 2009 в 09:57

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

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

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

class Foo(object):
    bar = 1
    def bah(self):    
        print self.bar
59
ответ дан vartec 15 August 2018 в 15:02
поделиться
  • 1
    Почему бы не просто Foo.bar, а вместо self.__class__.bar? – mk12 13 September 2009 в 21:59
  • 2
    @ Mk12: Когда у вас есть наследование классов, переменная класса «может быть в базовом классе или подклассе. К чему вы хотите обратиться? Зависит от того, что вы пытаетесь сделать. Foo.bar всегда будет ссылаться на атрибут указанного класса - который может быть базовым классом или подклассом. self.__class__.bar будет ссылаться на любой класс, экземпляр которого является типом. – Craig McQueen 11 December 2009 в 05:47
  • 3
    Теперь мы достигли этого неудачного момента, когда мы стали настолько осведомлены о деталях языка, который мы можем различить между двумя точно настроенными вариантами использования. Это действительно зависит от того, что вы хотите сделать, но многие люди не будут следить за такими тонкостями. – holdenweb 14 December 2011 в 12:19
  • 4
    Кстати, это редкое использование «переменной класса». Гораздо более распространенный, чтобы определить его в определенном классе, здесь Foo. Это полезная информация для некоторых сложных ситуаций программирования. Но почти наверняка не тот исходный вопрос, который нужен в качестве ответа (любой, кто нуждается в ЭТОМ ответе, уже знает, как сделать Foo.bar). +1, потому что я чему-то научился. – ToolmakerSteve 25 November 2013 в 19:05
  • 5
    Я узнаю, когда использовать переменные и методы класса (в отличие от переменных и методов экземпляра). Если вы хотите получить доступ к переменной класса в методе экземпляра, необходимо ли использовать self.__class__.bar? Я заметил, что self.bar работает, хотя bar является переменной класса, а не переменной экземпляра. – Bill 29 March 2015 в 18:30
Другие вопросы по тегам:

Похожие вопросы: