2016-08-10 5 views
0

У меня есть файл А с 2-мя глобальными переменнымиДоступ к глобальным переменным из тестового файла

root = "" 
crumbs = [] 


def read(line): 
    global root, crumbs 

    line = line.strip() 
    open_tag = is_valid_open(line) 
    kv = get_kv(line) 

    if open_tag is not None: 
     root += open_tag + "." 
     print root      <---------- prints stuff 

    elif kv is not None: 
     crumbs.append(kv[0] + "=" + kv[1]) 
     print crumbs     <---------- prints stuff 

У меня есть тест, от которого я

from A import read, root, crumbs 

я кормить его некоторые данные

read('<a>') 
    read('<b>') 
    read('<d>acceptor</d>') 

И распечатать результаты

print "." + root + "."    <---------- prints NOTHING 
    print "." + str(crumbs) + "."  <---------- prints stuff 

Почему у меня есть доступ к списку, но не строка из моего тестового файла? Похоже, что если кто-то работает, другой должен работать.

+0

Plz show 'open_tag' декларация и' kv' декларация –

+0

@VaibhavBajaj - обновлено – JAM

+0

Вы уверены, что open_tag почему-то не получает значение 'None' при вызове из другого файла в объявлении? –

ответ

5

Короче говоря, это потому, что += делает разные вещи для списков и строк.

  • Строки неизменяемы. Поэтому root += ... в вашем A.py создает новую строку и присваивает ее root. Были две ссылки на root: один в A.py и один в вашем тестовом скрипте. Строка root += изменяет только root в A.py, так как это единственное, что функция в A.py имеет доступ к. root в вашем тестовом модуле не изменяется.

  • Списки являются изменяемыми. Поэтому crumbs += изменяет существующий список и не меняет то, что указывает crumbs. Поскольку crumbs по-прежнему относится к тому же списку как в A.py, так и в вашем тестовом модуле, вы видите изменение в вашем тестовом модуле.

Это становится ясным, если вы пишете эти заявления без +=:

  • root = root + ..., очевидно, делает новую строку и изменяет root чтобы указать на него
  • crumbs.extend(...) очевидно не сделать новый список и не меняет то, что crumbs указывает на

Эта небольшая путаница может возникнуть, когда вы пытаетесь получить доступ к переменным между модулями без использования полностью квалифицированных имен. Вы получаете несколько имен, которые изначально (после import) относятся к одному и тому же объекту, но потом что-то меняет это.

Решение только для import A и ссылается на A.root и A.crumbs в вашем тестовом сценарии. Таким образом, для этих объектов существует только одно каноническое имя, а имена «принадлежат» модулю, который их изменяет.

+0

. Вы не «импортировали A» в ответ, который вам предложили. –

+0

Большое вам спасибо. Отлично – JAM

Смежные вопросы