Вы используете "глобальный" оператор в 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, которое запрещает это в нашем производственном коде. Я действительно считаю, что этого вообще не должно быть.
Я использовал его в быстрых и грязных одноразовых скриптах, чтобы автоматизировать одноразовую задачу. Что-нибудь большее, чем это, или то, что нужно использовать повторно, и я найду более элегантный способ.
Один или два раза. Но это всегда было хорошей отправной точкой для рефакторинга.
Если я могу избежать этого, нет. И, насколько мне известно, всегда есть способ избежать этого. Но я не утверждаю, что это также совершенно бесполезно