Использование глобальных переменных в функции

Как создать или использовать глобальную переменную в функции?

Если я создаю глобальную переменную в одной функции, как я могу использовать эту глобальную переменную в другой функции? Нужно ли хранить глобальную переменную в локальной переменной функции, которая нуждается в ее доступе?

вопрос задан 8.01.2009
user46646
45153 репутация

18 ответов


  • 3579 рейтинг

    Вы можете использовать глобальную переменную в других функциях, объявив ее как global в каждой назначенной ей функции:

     globvar = 0
    
    def set_globvar_to_one():
        global globvar    # Needed to modify global copy of globvar
        globvar = 1
    
    def print_globvar():
        print(globvar)     # No need for global declaration to read value of globvar
    
    set_globvar_to_one()
    print_globvar()       # Prints 1
     

    Я предполагаю, что причина в том, что, поскольку глобальные переменные настолько опасны, Python хочет убедиться, что вы действительно знаете, что именно вы играете, явно требуя ключевое слово global .

    См. Другие ответы, если вы хотите поделиться глобальной переменной между модулями.

    ответ дан Paul Stephenson, с репутацией 44940, 8.01.2009
  • 674 рейтинг

    Если я правильно понимаю вашу ситуацию, то, что вы видите, является результатом того, как Python обрабатывает локальные (функциональные) и глобальные (модули) пространства имен.

    Скажем, у вас есть такой модуль:

     # sample.py
    myGlobal = 5
    
    def func1():
        myGlobal = 42
    
    def func2():
        print myGlobal
    
    func1()
    func2()
     

    Вы можете ожидать, что это напечатает 42, но вместо этого печатает 5. Как уже упоминалось, если вы добавите объявление « global » в func1() , тогда func2() напечатает 42.

     def func1():
        global myGlobal
        myGlobal = 42
     

    Что здесь происходит, так это то, что Python предполагает, что любое имя, которое назначено в любом месте функции, является локальным для этой функции, если явно не указано иное. Если это только чтение из имени, а имя не существует локально, оно попытается найти имя в любых содержащихся в нем областях (например, глобальную область модуля).

    Поэтому, когда вы назначаете 42 имени myGlobal , Python создает локальную переменную, которая затеняет глобальную переменную с тем же именем. Это местное выходит за рамки и собирает мусор, когда func1() возвращается; Между тем, func2() никогда не может видеть ничего, кроме глобального (немодифицированного) глобального имени. Обратите внимание, что это решение пространства имен происходит во время компиляции, а не во время выполнения - если вы должны были прочитать значение myGlobal внутри func1() прежде чем назначать ему, вы получите UnboundLocalError , потому что Python уже решил, что он должен быть локальным но он еще не имел никакого значения, связанного с ним. Но, используя оператор « global », вы указываете Python, что он должен искать в другом месте имя вместо того, чтобы назначать ему локально.

    (Я полагаю, что это поведение произошло в основном за счет оптимизации локальных пространств имен - без этого поведения, Python VM потребовалось бы выполнить по крайней мере три поиска имен каждый раз, когда новое имя назначается внутри функции (чтобы гарантировать, что имя didn ' t уже существуют на модуле /встроенном уровне), что значительно замедлит очень частое выполнение операции.)

    ответ дан Jeff Shannon, с репутацией 7651, 8.01.2009
  • 180 рейтинг

    Вы можете изучить понятие пространств имен . В Python модуль является естественным местом для глобальных данных:

    Каждый модуль имеет свою собственную таблицу личных символов, которая используется в качестве глобальной таблицы символов всеми функциями, определенными в модуле. Таким образом, автор модуля может использовать глобальные переменные в модуле, не беспокоясь о случайных столкновениях с глобальными переменными пользователя. С другой стороны, если вы знаете, что делаете, вы можете коснуться глобальных переменных модуля с теми же обозначениями, которые используются для обозначения его функций, modname.itemname .

    Здесь описывается конкретное использование глобального модуля в-модуле - как-до-i-share-global-variables-through-modules , и для полноты содержимого здесь можно разделить:

    Канонический способ обмена информацией между модулями в рамках одной программы - создать специальный модуль конфигурации (часто называемый config или cfg). Просто импортируйте модуль конфигурации во все модули вашего приложения; модуль становится доступным как глобальное имя. Поскольку есть только один экземпляр каждого модуля, любые изменения, внесенные в объект модуля, отражаются повсюду. Например:

    Файл: config.py

     x = 0   # Default value of the 'x' configuration setting
     

    Файл: mod.py

     import config
    config.x = 1
     

    Файл: main.py

     import config
    import mod
    print config.x
     
    ответ дан gimel, с репутацией 54442, 8.01.2009
  • 76 рейтинг

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

     >>> import dis
    >>> def foo():
    ...     global bar
    ...     baz = 5
    ...     print bar
    ...     print baz
    ...     print quux
    ... 
    >>> dis.disassemble(foo.func_code)
      3           0 LOAD_CONST               1 (5)
                  3 STORE_FAST               0 (baz)
    
      4           6 LOAD_GLOBAL              0 (bar)
                  9 PRINT_ITEM          
                 10 PRINT_NEWLINE       
    
      5          11 LOAD_FAST                0 (baz)
                 14 PRINT_ITEM          
                 15 PRINT_NEWLINE       
    
      6          16 LOAD_GLOBAL              1 (quux)
                 19 PRINT_ITEM          
                 20 PRINT_NEWLINE       
                 21 LOAD_CONST               0 (None)
                 24 RETURN_VALUE        
    >>> 
     

    Посмотрите, как baz, который появляется в левой части задания в foo() , является единственной переменной LOAD_FAST .

    ответ дан SingleNegationElimination, с репутацией 108014, 12.07.2011
  • 50 рейтинг

    Если вы хотите ссылаться на глобальную переменную в функции, вы можете использовать ключевое слово global, чтобы объявить, какие переменные являются глобальными. Вам не нужно использовать его во всех случаях (как кто-то здесь неправильно утверждает) - если имя, указанное в выражении, не может быть найдено в локальной области или областям функций, в которых эта функция определена, она просматривается среди глобальных переменные.

    Однако, если вы назначаете новую переменную, не объявленную как глобальную в функции, она неявно объявляется как локальная, и она может затенять любую существующую глобальную переменную с тем же именем.

    Кроме того, глобальные переменные полезны, в отличие от некоторых фанатиков ООП, которые заявляют об обратном - особенно для небольших сценариев, где ООП является излишним.

    ответ дан J S, с репутацией 762, 8.01.2009
  • 37 рейтинг

    В дополнение к уже существующим ответам и сделать это более запутанным:

    В Python переменные, которые только ссылаются внутри функции, являются неявно глобальными . Если переменной присваивается новое значение в любом месте тела функции, предполагается, что она является локальной . Если переменной присвоено новое значение внутри функции, переменная неявно локальна, и вам нужно явно объявить ее как «глобальную».

    Хотя сначала это немного удивительно, это объясняет момент. С одной стороны, требуя глобальных для назначенных переменных, это бар против непреднамеренных побочных эффектов. С другой стороны, если для глобальных ссылок требуется глобальное требование, вы все время будете использовать глобальный. Вы должны объявить глобальным все ссылки на встроенную функцию или на компонент импортированного модуля. Этот беспорядок победил бы полезность глобальной декларации для выявления побочных эффектов.

    Источник: Каковы правила для локальных и глобальных переменных в Python? ,

    ответ дан Rauni Lillemets, с репутацией 1466, 4.07.2014
  • 32 рейтинг

    Если я создаю глобальную переменную в одной функции, как я могу использовать эту переменную в другой функции?

    Мы можем создать глобальную функцию со следующей функцией:

     def create_global_variable():
        global global_variable # must declare it to be a global first
        # modifications are thus reflected on the module's global scope
        global_variable = 'Foo' 
     

    Написание функции фактически не запускает ее код. Таким образом, мы называем функцию create_global_variable :

     >>> create_global_variable()
     

    Использование глобальных переменных без изменений

    Вы можете использовать его только в том случае, если вы не ожидаете изменить тот объект, на который он указывает:

    Например,

     def use_global_variable():
        return global_variable + '!!!'
     

    и теперь мы можем использовать глобальную переменную:

     >>> use_global_variable()
    'Foo!!!'
     

    Модификация глобальной переменной изнутри функции

    Чтобы указать глобальную переменную на другом объекте, вам нужно снова использовать глобальное ключевое слово:

     def change_global_variable():
        global global_variable
        global_variable = 'Bar'
     

    Обратите внимание, что после записи этой функции код, фактически меняющий ее, все еще не запущен:

     >>> use_global_variable()
    'Foo!!!'
     

    Поэтому после вызова функции:

     >>> change_global_variable()
     

    мы видим, что глобальная переменная была изменена. Имя global_variable теперь указывает на 'Bar' :

     >>> use_global_variable()
    'Bar!!!'
     

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

    Локальные переменные с тем же именем

    Если вы создадите локальную переменную с тем же именем, она затмит глобальную переменную:

     def use_local_with_same_name_as_global():
        # bad name for a local variable, though.
        global_variable = 'Baz' 
        return global_variable + '!!!'
    
    >>> use_local_with_same_name_as_global()
    'Baz!!!'
     

    Но использование этой ложной локальной переменной не изменяет глобальную переменную:

     >>> use_global_variable()
    'Bar!!!'
     

    Обратите внимание, что вам следует избегать использования локальных переменных с теми же именами, что и глобальные, если вы точно не знаете, что делаете, и у вас есть все основания для этого. Я еще не сталкивался с такой причиной.

    ответ дан Aaron Hall, с репутацией 153756, 1.01.2016
  • 29 рейтинг

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

     import multiprocessing
    import os
    import random
    import sys
    import time
    
    def worker(new_value):
        old_value = get_value()
        set_value(random.randint(1, 99))
        print('pid=[{pid}] '
              'old_value=[{old_value:2}] '
              'new_value=[{new_value:2}] '
              'get_value=[{get_value:2}]'.format(
              pid=str(os.getpid()),
              old_value=old_value,
              new_value=new_value,
              get_value=get_value()))
    
    def get_value():
        global global_variable
        return global_variable
    
    def set_value(new_value):
        global global_variable
        global_variable = new_value
    
    global_variable = -1
    
    print('before set_value(), get_value() = [%s]' % get_value())
    set_value(new_value=-2)
    print('after  set_value(), get_value() = [%s]' % get_value())
    
    processPool = multiprocessing.Pool(processes=5)
    processPool.map(func=worker, iterable=range(15))
     

    Вывод:

     before set_value(), get_value() = [-1]
    after  set_value(), get_value() = [-2]
    pid=[53970] old_value=[-2] new_value=[ 0] get_value=[23]
    pid=[53971] old_value=[-2] new_value=[ 1] get_value=[42]
    pid=[53970] old_value=[23] new_value=[ 4] get_value=[50]
    pid=[53970] old_value=[50] new_value=[ 6] get_value=[14]
    pid=[53971] old_value=[42] new_value=[ 5] get_value=[31]
    pid=[53972] old_value=[-2] new_value=[ 2] get_value=[44]
    pid=[53973] old_value=[-2] new_value=[ 3] get_value=[94]
    pid=[53970] old_value=[14] new_value=[ 7] get_value=[21]
    pid=[53971] old_value=[31] new_value=[ 8] get_value=[34]
    pid=[53972] old_value=[44] new_value=[ 9] get_value=[59]
    pid=[53973] old_value=[94] new_value=[10] get_value=[87]
    pid=[53970] old_value=[21] new_value=[11] get_value=[21]
    pid=[53971] old_value=[34] new_value=[12] get_value=[82]
    pid=[53972] old_value=[59] new_value=[13] get_value=[ 4]
    pid=[53973] old_value=[87] new_value=[14] get_value=[70]
     
    ответ дан Bohdan, с репутацией 8557, 3.10.2013
  • 20 рейтинг

    То, что вы говорите, - это использовать такой метод:

     globvar = 5
    
    def f():
        var = globvar
        print(var)
    
    f()  # Prints 5
     

    Но лучший способ - использовать глобальную переменную следующим образом:

     globavar = 5
    def f():
        global globvar
        print(globvar)
    f()   #prints 5
     

    Оба дают одинаковый результат.

    ответ дан gxyd, с репутацией 394, 4.12.2014
  • 20 рейтинг

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

    Следующим образом:

     var = "test"
    
    def printGlobalText():
        global var #wWe are telling to explicitly use the global version
        var = "global from printGlobalText fun."
        print "var from printGlobalText: " + var
    
    def printLocalText():
        #We are NOT telling to explicitly use the global version, so we are creating a local variable
        var = "local version from printLocalText fun"
        print "var from printLocalText: " + var
    
    printGlobalText()
    printLocalText()
    """
    Output Result:
    var from printGlobalText: global from printGlobalText fun.
    var from printLocalText: local version from printLocalText
    [Finished in 0.1s]
    """
     
    ответ дан Mohamed El-Saka, с репутацией 421, 20.12.2014
  • 18 рейтинг

    Фактически вы не храните глобальную локальную переменную, просто создавая локальную ссылку на тот же объект, на который ссылается ваша оригинальная глобальная ссылка. Помните, что почти все в Python - это имя, относящееся к объекту, и ничего не копируется в обычной работе.

    Если вам не нужно было явно указывать, когда идентификатор должен был ссылаться на предопределенный глобальный, то вы, вероятно, должны явно указывать, когда вместо идентификатора будет новая локальная переменная (например, с чем-то вроде команды «var» см. в JavaScript). Поскольку локальные переменные более распространены, чем глобальные переменные в любой серьезной и нетривиальной системе, система Python имеет больший смысл в большинстве случаев.

    У вас может быть язык, который пытался угадать, используя глобальную переменную, если она существовала, или создавая локальную переменную, если это не так. Однако это было бы очень подвержено ошибкам. Например, импорт другого модуля может непреднамеренно ввести глобальную переменную этим именем, изменив поведение вашей программы.

    ответ дан Kylotan, с репутацией 16396, 9.01.2009
  • 18 рейтинг

    Как оказалось, ответ всегда прост.

    Вот небольшой примерный модуль с простым способом показать его в определении main :

     def five(enterAnumber,sumation):
        global helper
        helper  = enterAnumber + sumation
    
    def isTheNumber():
        return helper
     

    Вот как это показать в определении main :

     import TestPy
    
    def main():
        atest  = TestPy
        atest.five(5,8)
        print(atest.isTheNumber())
    
    if __name__ == '__main__':
        main()
     

    Этот простой код работает именно так, и он будет выполняться. Я надеюсь, что это помогает.

    ответ дан user2876408, с репутацией 181, 13.10.2013
  • 15 рейтинг

    Попробуй это:

     def x1():
        global x
        x = 6
    
    def x2():
        global x
        x = x+1
        print x
    
    x = 5
    x1()
    x2()  # output --> 7
     
    ответ дан Sagar Mehta, с репутацией 187, 4.02.2015
  • 12 рейтинг

    Следуя и добавляя, используйте файл, чтобы содержать все глобальные переменные, все объявленные локально, а затем «импортировать как»:

    Файл initval.py

     Stocksin = 300
    Prices = []
     

    Файл getstocks.py

     import  initval as  iv
    
    Def   getmystocks (): 
         iv.Stocksin  = getstockcount ()
    
    
    Def getmycharts ():
        For ic in range (0,iv.Stocksin):
     

    .....

    ответ дан Sagar Mehta, с репутацией 187, 24.10.2015
  • 10 рейтинг

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

     import numpy as np
    
    hostValue = 3.14159
    hostArray = np.array([2., 3.])
    hostMatrix = np.array([[1.0, 0.0],[ 0.0, 1.0]])
    
    def func1():
        global hostValue    # mandatory, else local.
        hostValue = 2.0
    
    def func2():
        global hostValue    # mandatory, else UnboundLocalError.
        hostValue += 1.0
    
    def func3():
        global hostArray    # mandatory, else local.
        hostArray = np.array([14., 15.])
    
    def func4():            # no need for globals
        hostArray[0] = 123.4
    
    def func5():            # no need for globals
        hostArray[1] += 1.0
    
    def func6():            # no need for globals
        hostMatrix[1][1] = 12.
    
    def func7():            # no need for globals
        hostMatrix[0][0] += 0.33
    
    func1()
    print "After func1(), hostValue = ", hostValue
    func2()
    print "After func2(), hostValue = ", hostValue
    func3()
    print "After func3(), hostArray = ", hostArray
    func4()
    print "After func4(), hostArray = ", hostArray
    func5()
    print "After func5(), hostArray = ", hostArray
    func6()
    print "After func6(), hostMatrix = \n", hostMatrix
    func7()
    print "After func7(), hostMatrix = \n", hostMatrix
     
    ответ дан Mike Lampton, с репутацией 111, 7.01.2016
  • 9 рейтинг

    Если у вас есть локальная переменная с тем же именем, вы можете использовать функцию globals() .

     globals()['your_global_var'] = 42
     
    ответ дан Martin Thoma, с репутацией 36890, 7.04.2017
  • 5 рейтинг

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

     from pickle import load
    def loaditem(name):
        with open(r"C:\pickle\file\location"+"\{}.dat".format(name), "rb") as openfile:
            globals()[name] = load(openfile)
        return True
     

    а также

     from pickle import dump
    def dumpfile(name):
        with open(name+".dat", "wb") as outfile:
            dump(globals()[name], outfile)
        return True
     

    Просто позвольте вам выгружать /загружать переменные из глобального пространства имен и в него. Супер удобный, без шума, без суеты. Довольно уверен, что это только python 3.

    ответ дан Rafaël Dera, с репутацией 282, 5.09.2017
  • 5 рейтинг

    Укажите пространство имен классов, в котором вы хотите, чтобы изменения отображались.

    В этом примере бегун использует max из файловой конфигурации. Я хочу, чтобы мой тест изменил значение max, когда бегун использует его.

    Основной /config.py

     max = 15000
     

    Основной /runner.py

     from main import config
    def check_threads():
        return max < thread_count 
     

    Тесты /runner_test.py

     from main import runner                # <----- 1. add file
    from main.runner import check_threads
    class RunnerTest(unittest):
       def test_threads(self):
           runner.max = 0                  # <----- 2. set global 
           check_threads()
     
    ответ дан llewellyn falco, с репутацией 1816, 19.08.2017