Вопрос по python – Как я могу получить доступ к глобальной переменной внутри класса в Python

40

У меня есть это:

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?

Обратите внимание, что цель классов - устранить (действительно) глобальное состояние и управлять им внутри классов и объектов. Marcin

Ваш Ответ

5   ответов
1

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)
Error: User Rate Limit Exceeded
1

a = 0

class b():
    global a
    a = 10

>>> a
10
77

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 заявление:

The global statement is a declaration which holds for the entire current code block.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded torayeff
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
12

global объявление внутри вашей функции:

class TestClass():
    def run(self):
        global g_c
        for i in range(10):
            g_c = 1
            print g_c
4

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

Причина того, чтоg_c не был измененrun Функция в вашем классе заключается в том, что ссылка на глобальное имя вg_c не был установлен точно в рамках функции. То, как Python обрабатывает глобальные объявления, на самом деле довольно сложно. Командаglobal g_c имеет два эффекта:

Preconditions the entrance of the key "g_c" into the dictionary accessible by the built-in function, globals(). However, the key will not appear in the dictionary until after a value is assigned to it.

(Potentially) alters the way Python looks for the variable g_c within the current method.

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

Однако, если происходит команда присваиванияanywhere в методе Python по умолчанию находит имяg_c внутри локальных переменных. Это верно даже тогда, когда ссылка происходит перед фактическим назначением, что приведет к классической ошибке:

UnboundLocalError: local variable 'g_c' referenced before assignment

Теперь, если декларацияglobal g_c происходитanywhere в методе, даже после любой ссылки или присваивания, 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()
Error: User Rate Limit Exceeded

Похожие вопросы