У меня есть это:
g_c = 0
class TestClass():
global g_c
def run(self):
for i in range(10):
g_c = 1
print g_c
t = TestClass()
t.run()
print g_c
как я могу изменить мою глобальную переменную g_c?
У меня есть это:
g_c = 0
class TestClass():
global g_c
def run(self):
for i in range(10):
g_c = 1
print g_c
t = TestClass()
t.run()
print g_c
как я могу изменить мою глобальную переменную g_c?
Объявив его global
внутри функции, которая обращается к нему:
g_c = 0
class TestClass():
def run(self):
global g_c
for i in range(10):
g_c = 1
print g_c
Документация Python говорит об этом, в инструкции global
:
Глобальный оператор - это объявление, которое выполняется для всего текущего блока кода.
Вам нужно переместить объявление global
внутри вашей функции:
class TestClass():
def run(self):
global g_c
for i in range(10):
g_c = 1
print g_c
Я понимаю, что использование глобальной переменной иногда является наиболее удобной задачей, особенно в тех случаях, когда использование класса делает намного проще (например, multiprocessing
). Я столкнулся с той же проблемой с объявлением глобальных переменных и вычислил ее с некоторыми экспериментами.
Причина, по которой g_c
не была изменена функцией run
внутри вашего класса, заключается в том, что ссылка на глобальное имя внутри g_c
не была точно установлена внутри функции. То, как Python обрабатывает глобальную декларацию, на самом деле довольно сложно. Команда global g_c
имеет два эффекта:
Предустановляет вход ключа "g_c"
в словарь, доступный встроенной функцией, globals()
. Однако ключ не будет отображаться в словаре до тех пор, пока ему не будет присвоено значение.
(Потенциально) изменяет способ поиска Python переменной g_c
в текущем методе.
Полное понимание (2) является особенно сложным. Прежде всего, это только потенциально изменяет, потому что, если в методе не возникает присвоение имени g_c
, то Python по умолчанию ищет его среди globals()
. Это на самом деле довольно распространенная вещь, как в случае ссылок в модуле метода, которые полностью импортируются в начале кода.
Однако, если команда назначения встречается где угодно внутри метода, Python по умолчанию находит имя g_c
внутри локальных переменных. Это справедливо даже тогда, когда ссылка происходит до фактического назначения, что приведет к классической ошибке:
UnboundLocalError: local variable 'g_c' referenced before assignment
Теперь, если декларация global g_c
происходит в любом месте метода, даже после любой ссылки или назначения, Python по умолчанию находит имя g_c
в глобальных переменных. Однако, если вы чувствуете себя экспериментально и размещаете декларацию после ссылки, вы будете вознаграждены предупреждением:
SyntaxWarning: name 'g_c' is used prior to global declaration
Если вы думаете об этом, то способ, которым глобальная декларация работает на Python, четко вплетена и согласуется с тем, как работает Python. Это просто, когда вы действительно хотите, чтобы глобальная переменная работала, норма становится раздражающей.
Вот код, в котором суммируется то, что я только что сказал (с несколькими наблюдениями):
g_c = 0
print ("Initial value of g_c: " + str(g_c))
print("Variable defined outside of method automatically global? "
+ str("g_c" in globals()))
class TestClass():
def direct_print(self):
print("Directly printing g_c without declaration or modification: "
+ str(g_c))
#Without any local reference to the name
#Python defaults to search for the variable in globals()
#This of course happens for all the module names you import
def mod_without_dec(self):
g_c = 1
#A local assignment without declaring reference to global variable
#makes Python default to access local name
print ("After mod_without_dec, local g_c=" + str(g_c))
print ("After mod_without_dec, global g_c=" + str(globals()["g_c"]))
def mod_with_late_dec(self):
g_c = 2
#Even with a late declaration, the global variable is accessed
#However, a syntax warning will be issued
global g_c
print ("After mod_with_late_dec, local g_c=" + str(g_c))
print ("After mod_with_late_dec, global g_c=" + str(globals()["g_c"]))
def mod_without_dec_error(self):
try:
print("This is g_c" + str(g_c))
except:
print("Error occured while accessing g_c")
#If you try to access g_c without declaring it global
#but within the method you also alter it at some point
#then Python will not search for the name in globals()
#!!!!!Even if the assignment command occurs later!!!!!
g_c = 3
def sound_practice(self):
global g_c
#With correct declaration within the method
#The local name g_c becomes an alias for globals()["g_c"]
g_c = 4
print("In sound_practice, the name g_c points to: " + str(g_c))
t = TestClass()
t.direct_print()
t.mod_without_dec()
t.mod_with_late_dec()
t.mod_without_dec_error()
t.sound_practice()
class flag:
## Store pseudo-global variables here
keys=False
sword=True
torch=False
## test the flag class
print('______________________')
print(flag.keys)
print(flag.sword)
print (flag.torch)
## now change the variables
flag.keys=True
flag.sword= not flag.sword
flag.torch=True
print('______________________')
print(flag.keys)
print(flag.sword)
print (flag.torch)