Форум программистов, компьютерный форум, киберфорум
Python для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.61/18: Рейтинг темы: голосов - 18, средняя оценка - 4.61
325 / 304 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
1

NameError: global name 'self' is not defined

14.01.2019, 16:00. Показов 3774. Ответов 9
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
На фоне параллельного изучения js я обнаружил, что довольно неглубоко знаю python. Например, о такой фиче, как использование функций в качестве объектов. Читал, что Гвидо вкладывал в функции понятия сабклассов - то есть объектов, которые имеют поведение как классов, но, видимо, с какими-то ограничениями

В частности для меня остается загадкой, почему код:
Python
1
2
3
4
5
6
7
def f():
    self.g=5
    print 'a'
f.name = 0
 
print "Hello, world!"
print f.name
Выполняется без ошибок. То есть по факту, как в js: функция, как объект, может иметь поле

Но если попробовать инициализировать f как объект:
Python
1
2
3
4
5
6
7
8
def f():
    self.g=5
    print 'a'
f.name = 0
 
print "Hello, world!"
print f.name
d = f()
получается такая ошибка:
Python
1
2
3
4
5
6
7
Error(s), warning(s):
Traceback (most recent call last):
  File "source_file.py", line 10, in <module>
    d = f()
  File "source_file.py", line 4, in f
    self.g=5
NameError: global name 'self' is not defined
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.01.2019, 16:00
Ответы с готовыми решениями:

Не работает код. Ошибка NameError: global name 'Pizza' is not defined. Что я не правильно делаю?
from livewires import games games.init(screen_width = 500, screen_height =380, fps = 20) class...

NameError: name 'n' is not defined
Всем привет! В это коде постоянно вылазит ошибка &quot;NameError: name 'name' is not defined&quot; я не могу...

NameError: name 'a' is not defined
ver='\nверсия 1' def funk(a, b): global ver print('весы', ver) a=int(input('первое...

NameError: name 'self' is not defined
Здравствуйте. Пишу с горем пополам бота, сто раз уже менял логику, теперь вылетает ошибка: ...

9
Просто Лис
Эксперт Python
5731 / 3530 / 1055
Регистрация: 17.05.2012
Сообщений: 10,359
Записей в блоге: 9
14.01.2019, 16:58 2
Лучший ответ Сообщение было отмечено mik-a-el как решение

Решение

Логично, ведь переменной self не существует.

Python
1
2
3
4
5
def f():
    print(f.name)
f.name = 0
 
f()
Добавлено через 46 секунд
Python
1
2
3
4
5
6
7
def f():
    f.name += 1
f.name = 0
 
print(f.name)
f()
print(f.name)
1
1728 / 968 / 199
Регистрация: 22.02.2018
Сообщений: 2,694
Записей в блоге: 6
14.01.2019, 19:52 3
Цитата Сообщение от netBool Посмотреть сообщение
Читал, что Гвидо вкладывал в функции понятия сабклассов
Вы это наверняка читали не у Гвидо. А фантазии толкователей не стоит принимать всерьез, если они не имеют общепризнанного авторитета, как например М.Лутц. Хотя и в изложении последнего встречаются ошибки, хотя и редко.
Итак, что такое функции. В питоне это объекты, как и многие другие объекты, числа, списки, словари и т.д. Классы кстати , это тоже объекты. Особенность классов, это генерировать экземпляры (объекты), которые все обладают определенным заранее заданным набором атрибутов, которые задаются внутри класса. Функции, определенные внутри класса, называют методами. И только они могут иметь (или не иметь) аргумент self. У Вас присутствует self, но не описан класс. Такой код бессмысленный, и нет возможности обсуждать его работу.

Добавлено через 14 минут
Рыжий Лис, все правильно Вам написал. От себя добавлю. В первом примере объекту-функции f присваивается атрибут и его значение. Ниже выводится значение этого атрибута. При этом вызов функции не осуществляется. Вызов функции осуществляется круглыми скобками, которые должны находится после имени функции.
И так, в первом примере вызов функции не осуществляется, поэтому не проявляется ошибка внутри функции, а именно присутствие неопределенного имени self. Во втором же примере осуществляется вызов функции d = f(), поэтому работает ее содержимое, и выявляется ошибка внутри функции.

Добавлено через 1 час 2 минуты
Цитата Сообщение от Viktorrus Посмотреть сообщение
И только они могут иметь (или не иметь) аргумент self
Тут я не верно выразился, имя self можно использовать в любом месте, просто в питон принято это имя давать в качестве обобщенного объекта класса, как аргумент в методе __init__, инициализирующим атрибуты общие для всех экземпляров данного класса.
1
325 / 304 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
19.01.2019, 12:45  [ТС] 4
Рыжий Лис,
Логично, ведь переменной self не существует.
Мда, действительно. По идее функцию надо было бы переписать def f(self):. Но тогда в нее надо передать экземпляр класса этой функции, т.е. self...:

Python
1
2
3
4
def f(self):
    self.g=5
    print 'construct'
    return self
И вызов выглядел бы не совсем удобно:

Python
1
print f(f).g
Цитата Сообщение от Viktorrus Посмотреть сообщение
Вы это наверняка читали не у Гвидо
Сначала на хабре, потом тут.

Цитата Сообщение от Viktorrus Посмотреть сообщение
Итак, что такое функции. В питоне это объекты, как и многие другие объекты, числа, списки, словари и т.д.
К числам, спискам и прочим я не могу добавить атрибут во время выполнения, как в примере выше к добавил к функции. Например, если я напишу int.r=7 или list.r = 7, то получу ошибку can't set attributes of built-in/extension type. Значит, они все-таки не совсем такие же?...


Я решил заморочиться и после прочтения ваших ответов пошел в тему на хабре и пришел к выводу, что использовать функцию для генерации нового объекта невозможно, т.к. на это способны только объекты типа 'type', которыми и являются классы:

Python
1
2
3
4
5
6
class A(object):
    pass
 
print A.__class__
 
>> <type 'type'>
А функции - это type 'function' либо на крайний случай type 'instancemethod', если это метод принадлежит классу. (Затем я наткнулся на другую статью и мне в голову взбрела мысль, а что если добавить как-то к <type 'function'> __metaclass__ = type? Но решения этому я так и не нашел )

Короче, поразмыслив мозгами, не придумал, ничего другого, как реализовать генератор объектов внутри функции через конструктор type:
Python
1
2
3
4
5
6
def f(self = type('f', (), {})):    
    self.g=5
    print 'a'
    return self
 
print f().g
Но проблема в методах: нельзя сделать:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
def f(self = type('f', (), {})):
    print 'a'
    
    def df():
        56    
    
    self.g=5
    self.gf=df
    
    return self
 
print f().g
print f().gf()
Для метода df компилятор требует передать первым параметром instance, а откуда его взять?

Единственное, что мне пришло в голову - это использовать staticmethod:

Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def f(self = type('f', (), {})):
    print 'a'
    
    @staticmethod
    def df():
        return self.g + 56    
    
    self.g=5
    self.gf=df
    
    return self
 
print f().g
print f().gf()
Неудобство этого способа в том, что надо каждый раз писать декоратор:
Python
1
self.func = staticmethod(lambda: self.g + 6)

Цитата Сообщение от Viktorrus Посмотреть сообщение
От себя добавлю. В первом примере объекту-функции f присваивается атрибут и его значение. Ниже выводится значение этого атрибута. При этом вызов функции не осуществляется. Вызов функции осуществляется круглыми скобками, которые должны находится после имени функции.
Я всегда об этом в питоне забываю. Привык, что в шарпе все подобные ошибки выскакивают на этапе компиляции не завимисо от того. будет ли код выполнен
0
Эксперт Python
5418 / 3842 / 1214
Регистрация: 28.10.2013
Сообщений: 9,554
Записей в блоге: 1
19.01.2019, 13:10 5
А что вы изобрести пытаетесь? Функция type() прекрасно выполняет задачу по генерации налету новых объектов и придумывать свой велосипед абсолютно не нужно.
0
1728 / 968 / 199
Регистрация: 22.02.2018
Сообщений: 2,694
Записей в блоге: 6
19.01.2019, 13:26 6
Цитата Сообщение от netBool Посмотреть сообщение
К числам, спискам и прочим я не могу добавить атрибут во время выполнения, как в примере выше к добавил к функции. Например, если я напишу int.r=7 или list.r = 7, то получу ошибку can't set attributes of built-in/extension type. Значит, они все-таки не совсем такие же?...
Я как то не задумывался, действительно все это объекты, но объекты разные и обладающие разными свойствами. Хотя все объекты принадлежат классу object, но видимо в методах класса object нет общего для всех экземпляров этого класса, то есть для всех объектов, метода присваивания экземпляру атрибута.
0
Просто Лис
Эксперт Python
5731 / 3530 / 1055
Регистрация: 17.05.2012
Сообщений: 10,359
Записей в блоге: 9
19.01.2019, 14:04 7
Цитата Сообщение от Garry Galler Посмотреть сообщение
А что вы изобрести пытаетесь?
Очевидно, что свой js с его прототипами
0
563 / 303 / 189
Регистрация: 20.05.2016
Сообщений: 592
19.01.2019, 16:25 8
Viktorrus, просто у каких-то объектов есть __dict__, у каких-то нет; у большинства стандартных его нет (у экземпляров самого object тоже, кстати, нету).
0
325 / 304 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
19.01.2019, 17:12  [ТС] 9
Цитата Сообщение от Garry Galler Посмотреть сообщение
Функция type() прекрасно выполняет задачу по генерации налету новых объектов
Собственно, к этому я и пришел

:
Python
1
2
3
4
5
6
def f(self = new('f')):
    
    self.g=5
    self.gf=staticmethod(lambda: self.g + 56)
    
    return self
где new = lambda x: type(x, (), {})

Вместо:

Python
1
2
3
4
5
6
class f(object):
    
    def __init__(self):
        
        self.g=5
        self.gf=lambda: self.g + 56
0
Просто Лис
Эксперт Python
5731 / 3530 / 1055
Регистрация: 17.05.2012
Сообщений: 10,359
Записей в блоге: 9
19.01.2019, 17:35 10
А смысл всего этого?
Python
1
2
3
4
5
6
7
8
9
new = lambda x: type(x, (), {})
 
def f(self=new('f')):
    self.g=5
    self.gf=staticmethod(lambda: self.g + 56)
    return self
 
f.g = 10
print(f().gf())  # 61
Добавлено через 4 минуты
Попробуйте декораторы:
Python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
def dec(func):
    func.g = 5
    def gf():
        return func.g
    func.gf = gf
    #def wrap(*args, **kwargs):
    return func
 
@dec
def f():
    return 43
 
print(f())
f.g = 10
print(f.gf())
0
19.01.2019, 17:35
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.01.2019, 17:35
Помогаю со студенческими работами здесь

NameError: name 'i' is not defined. Did you mean: 'id'?
a = 0 string = input() if string.isalpha == True: a += i print(string_1) Traceback (most...

NameError: name 'Tk' is not defined
from tkinter import * # Настройки окна root = Tk() root.resizable(width = False, height =...

NameError: name 'vk' is not defined
Что я делаю не так? При отправке сообщения пишет: &quot;Traceback (most recent call last): File...

NameError: name 'с' is not defined
what = input( &quot;Что делаем? (+,-): &quot; ) a = input(&quot;Введи первое число: &quot;) b = input(&quot;Введи второе...

NameError: name 'name' is not defined
ошибка, как исправить. программа должна создавать всплывающую подсказку для кнопки line 12, in...

NameError: name 'S' is not defined. Did you mean: 'Sa'?
подскажите в чем ошибка ...? #! /usr/bin/env python3 import math def FloatInput(message): ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru