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

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

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

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

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

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

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
...

или же

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Другие вопросы по тегам