Используете ли вы глобальный оператор в Python?

Я читал вопрос об операторе Python global ( "Python scope") и Я вспомнил о том, как часто я использовал это выражение, когда был новичком в Python (я часто использовал global), и как сейчас, спустя годы, я не использую его вообще, никогда. Я даже считаю это немного «не питоническим».

Вы используете это утверждение в Python? Изменилось ли ваше использование этого со временем?


person Aurelio Martin Massoni    schedule 28.09.2008    source источник


Ответы (12)


Я использую «глобальный» в таком контексте:

_cached_result = None
def myComputationallyExpensiveFunction():
    global _cached_result
    if _cached_result:
       return _cached_result

    # ... figure out result

    _cached_result = result
    return result

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

def myComputationallyExpensiveFunction():
    if myComputationallyExpensiveFunction.cache:
        return myComputationallyExpensiveFunction.cache

    # ... figure out result

    myComputationallyExpensiveFunction.cache = result
    return result
myComputationallyExpensiveFunction.cache = None
person Jerub    schedule 28.09.2008
comment
Я склонен использовать функцию «memoize» модуля декоратора в подобных случаях, но я не могу придраться к ясности вашего глобального использования :) - person Matthew Trevor; 29.09.2008
comment
Я не знал о возможности определения атрибута функции, такого как myComputationallyExpensiveFunction.cache, и использования его внутри тела функции, спасибо! - person Aurelio Martin Massoni; 30.09.2008
comment
Я никогда не слышал о назначении атрибута функции, это отличная вещь! Спасибо! - person brad; 03.09.2009
comment
2-я строка 2-го примера должна быть, если getattr(myComputationallyExpensiveFunction, cache, None):, иначе AttributeError. - person Andy Grover; 24.05.2012
comment
@AndyGrover Мне не нужно было этого делать, код отлично работает без него, и я не вижу никаких ошибок AttributeError (?) - person AJP; 10.03.2014

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

person ironfroggy    schedule 28.09.2008

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

discretes = 0
def use_discretes():
    #this global statement is a message to the parser to refer 
    #to the globally defined identifier "discretes"
    global discretes
    if using_real_hardware():
        discretes = 1
...

or

file1.py:
    def setup():
        global DISP1, DISP2, DISP3
        DISP1 = grab_handle('display_1')
        DISP2 = grab_handle('display_2')
        DISP3 = grab_handle('display_3')
        ...

file2.py:
    import file1

    file1.setup()
    #file1.DISP1 DOES NOT EXIST until after setup() is called.
    file1.DISP1.resolution = 1024, 768
person Adam Rossmiller    schedule 29.06.2011

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

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

person kender    schedule 28.09.2008

Объекты являются предпочтительным способом иметь нелокальное состояние, поэтому глобальное состояние требуется редко. Я не думаю, что будущий модификатор nonlocal также будет широко использоваться, я думаю, что он в основном предназначен для того, чтобы шепелявые перестали жаловаться :-)

person JacquesB    schedule 28.09.2008

Я использую его для глобальных параметров со сценариями командной строки и «optparse»:

мой main() анализирует аргументы и передает их любой функции, выполняющей работу сценария... но записывает предоставленные параметры в глобальный словарь «opts».

Параметры сценария оболочки часто изменяют поведение «листа», и неудобно (и не нужно) пропускать словарь «opts» через каждый список аргументов.

person Mike McCabe    schedule 05.01.2011

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

person André    schedule 28.09.2008

Редко. Я так и не нашел ему применения вообще.

person hydrapheetz    schedule 29.09.2008

Это может быть полезно в потоках для совместного использования состояния (с блокирующими механизмами вокруг него).

Тем не менее, я редко, если вообще когда-либо использую его.

person Corey Goldberg    schedule 29.09.2008

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

person Kena    schedule 10.10.2008

Раз или два. Но это всегда было хорошей отправной точкой для рефакторинга.

person zgoda    schedule 28.09.2008

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

person Community    schedule 28.09.2008