LINUX.ORG.RU

Python 2.7 и глобальные переменные

 ,


0

1

Доброго всем времени суток.

Есть несколько питоновских файлов, в одном описано некоторое количество общих классов и определена глобальная переменная для экземпляра одного из классов, работающего в dbus, в других файлах определены более специфичные классы, но результат их работы должен тоже попадать в dbus через глобальную переменную. В 1-ом файле с общими классами глобальная переменная работает хорошо и выводит в dbus всё что мне надо, но в других файлах сделав import first_file и вызвав экземпляр first_file.global_val получаю что данная переменная равна None, как при определении в 1-ом файле, но к этому времени я уже присвоил ей значение и по отладочному выводу это проверил. Подскажите как присвоить этой переменной значение, которое будет видно во всех файлах

Сделай её глобальной в других файлах. Кстати, а кто тебе сказал, что глобальные переменные — это хорошая идея?

anonymous ()
Ответ на: комментарий от anonymous

Если прописать в теле метода global first_file.global_val, будет ошибка; global global_val не работает.

Почему это плохая идея и какая идея хорошая?

seijuurou ()
Ответ на: комментарий от seijuurou

Почему это плохая идея

По возникшей проблеме ты наверное сам уже должен догадаться? )

и какая идея хорошая?

Отказаться от глобальной переменной. Использовать метод класса работающего с dbus или функцию.

Код показывай.

vvn_black ★★★★★ ()
Ответ на: комментарий от vvn_black

Это класс для работы с dbus, подобных методов-сигналов там много; они должны вызываться из других классов. Хотел сделать их статическими, но как-то не получается

class SDMObject(dbus.service.Object):
    log = logging.getLogger('SDMObject')
    def __init__(self, session_bus, main_thread):
        dbus.service.Object.__init__(self, session_bus, '/')
        self.main_thread = main_thread

    @dbus.service.method('ru.npoa.SDM', in_signature='', out_signature='s')
    def get_imei(self):
        return str(self.main_thread.imei)

seijuurou ()

Покажи минимальный примерный код, который у тебя не работает. Свои сверхсекретные исходники копипастить не нужно, просто минимальный пример: допустим, у тебя два модуля, в одном определена глобальная переменная, которую ты хочешь читать из другого модуля — покажи структуру кода. Потому что

в других файлах сделав import first_file и вызвав экземпляр first_file.global_val

должно прекрасно работать.

Virtuos86 ★★★★★ ()
Ответ на: комментарий от Virtuos86
#1st_file.py

#разные импорты
gloabal_val = None

def main():
 gloabal_val = Some_class() #Some_class наследник от object-а
 #запускаем потоки

#2nd_file.py
import 1st_file

class Other_class(object):
 def some_method(self):
  if 1st_file.gloabal_val != None: x=x+1
  else: self.log.debug("1st_file.gloabal_val is None") #программа всегда попадает в else

seijuurou ()
Ответ на: комментарий от anonymous

Хорошая идея это не использовать глобальные переменные

Насколько я помню, хорошая идея - это не менять глобальные переменные, а «не использовать» - частный случай для тех, кто не может удержаться от модификации.

DonkeyHot ★★★★★ ()
Ответ на: комментарий от anonymous

Когда засовываешь переменную в глобальный объект, она магическим образом перестает быть глобальной. А если делаеш аксессор в глобальном классе, то вообще в текущий скоп проваливается как влитая.

anonymous ()
Ответ на: комментарий от seijuurou

Когда ты в функции main делаешь gloabal_val = ты создаешь локальную переменную с именем global_val. Вот тебе наглядная демонстрация:

In [1]: x=1

In [2]: def main():
   ...:     x=x+1
   ...:

In [3]: main()
---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-3-58ca95c5b364> in <module>()
----> 1 main()

<ipython-input-2-ffb17d91c895> in main()
      1 def main():
----> 2     x=x+1
      3

UnboundLocalError: local variable 'x' referenced before assignment

Что делать - либо в начале функции main написать global global_val, чтобы дать понять интерпретатору что это глобальная переменная, либо положить ее в какой-нибудь глобальный mutable объект, например, поле класса, либо задавать ей значение на уровне модуля как написали выше, а не в функции.

pawnhearts ★★★★★ ()
Ответ на: комментарий от seijuurou
#1st_file.py

#разные импорты
global_val = None

def main():
 global_val = Some_class() #Some_class наследник от object-а
 #запускаем потоки

#2nd_file.py
import 1st_file

class Other_class(object):
 def some_method(self):
  if 1st_file.global_val != None: x=x+1
  else: self.log.debug("1st_file.global_val is None") #программа всегда попадает в else

Инструкция import считывает содержимое файла и выполняет его содержимое — _очень_ упрощенно говоря, — но выполняется только код в глобальном неймспейсе. В твоем случае это будет

#1st_file.py

#разные импорты
global_val = None
…
Функции не выполняются, а значит и main не выполняется. Поэтому после import 1st_file в global_val будет None.

Теперь вопрос: где у тебя точка входа в твоей программе? Что ты запускаешь? Условный 2nd_file.py? Или какой-то третий скрипт?

P.S. я бы еще задал вопрос, умеешь ли ты программировать, но это оффтопик…

Virtuos86 ★★★★★ ()
Ответ на: комментарий от Virtuos86

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

pawnhearts ★★★★★ ()
Ответ на: комментарий от seijuurou

нельзя так, нужно так:

#1st_file.py

#разные импорты
gloabal_val = None

def main():
 global gloabal_val
 gloabal_val = Some_class() #Some_class наследник от object-а
 #запускаем потоки

а лучше так:

def main():
 # В глобальной области переменную объявлять не надо, она туда испортируется
 nonlocal gloabal_val
 gloabal_val = Some_class() #Some_class наследник от object-а
 #запускаем потоки

а еще лучше не использовать глобальные переменные: создаешь класс, нужное делаешь свойствами(пропертями).

tz4678 ★★ ()
Ответ на: комментарий от pawnhearts

Он мог просто не показать код, где вызывается main, просили же вырезать все лишнее.

Гм, ну если в его случае main лишняя, то я бы попросил его обратить внимание на приписку к моему предыдущему комментарию.

В любом случае global_val в функции main это локальная переменная см. мой пост выше.

Сердечное спасибо за ликбез.

Virtuos86 ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.