Как установить значение словаря, находящегося в другом файле из другого файла? [Дубликат]

AlertDialog используют метод setCustomHeader, используя его и устанавливая пользовательский вид с шириной zero, zero. Он будет работать

LinearLayout linearLayout = new LinearLayout(getApplicationContext());
timePickerDialog.setCustomTitle(linearLayout);
109
задан Dan Homerick 27 September 2008 в 00:59
поделиться

12 ответов

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

a. py содержит

print foo

b.py содержит

import __builtin__
__builtin__.foo = 1
import a

В результате печатается «1».

Редактировать: модуль __builtin__ доступен как локальный символ __builtins__ - вот почему расхождение между двумя из этих ответов. Также обратите внимание, что __builtin__ был переименован в builtins в python3.

96
ответ дан Community 19 August 2018 в 07:40
поделиться
  • 1
    Любая причина, что вам не нравится эта ситуация? – Software Enthusiastic 5 August 2010 в 15:32
  • 2
    Во-первых, это нарушает ожидания людей, когда они читают код. «Какой здесь символ« foo »используется здесь? Почему я не вижу, где это определено? & Quot; – Curt Hagenlocher 6 August 2010 в 06:05
  • 3
    Это также подвержено разрушению, если будущая версия Python начнет использовать имя, которое вы выбрали в качестве фактического встроенного. – intuited 12 October 2010 в 02:20
  • 4
    Это хорошее решение для таких вещей, как совместное использование db-соединения с импортированными модулями. Как проверка работоспособности, я уверен, что импортированный модуль утверждает hasattr(__builtin__, "foo"). – Mike Ellis 18 January 2012 в 00:52
  • 5
    Я бы рекомендовал удалить импорт __builtin__ и просто использовать __builtins__ – B T 16 October 2012 в 00:58

Это звучит как изменение пространства имен __builtin__. Для этого:

import __builtin__
__builtin__.foo = 'some-value'

Не используйте __builtins__ напрямую (обратите внимание на дополнительные «s») - видимо, это может быть словарь или модуль. [3]

Теперь foo доступен для использования всюду.

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

Присвоение ему должно выполняться, как указано выше, только установка foo = 'some-other-value' будет устанавливать его только в текущем пространстве имен.

2
ответ дан awatts 19 August 2018 в 07:40
поделиться
  • 1
    Я помню (из comp.lang.python), что следует избегать использования встроенных встроенных функций ; вместо этого импортируйте builtin и используйте это, как предположил Курт Хагенлочер. – tzot 27 September 2008 в 01:13

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

def builtin_find(f, x, d=None):
    for i in x:
        if f(i):
            return i
    return d

import __builtin__
__builtin__.find = builtin_find

После запуска (например, путем импорта рядом с точкой входа) все ваши модули могут использовать find (), как будто, очевидно, он был встроен.

find(lambda i: i < 0, [1, 3, 0, -5, -10])  # Yields -5, the first negative.

Примечание: вы можете это сделать, конечно, с фильтром и другой строкой для проверки нулевой длины или с уменьшением в одном виде странная линия, но я всегда чувствовал, что это было странно.

1
ответ дан Brian Arsuaga 19 August 2018 в 07:40
поделиться

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

Когда есть только один такой модуль, я называю его "г". В нем я присваиваю значения по умолчанию для каждой переменной, которую я намерен рассматривать как глобальную. В каждом модуле, который использует любой из них, я не использую «from g import var», так как это приводит только к локальной переменной, которая инициализируется из g только во время импорта. Я делаю большинство ссылок в форме g.var и «g». служит постоянным напоминанием о том, что я имею дело с переменной, потенциально доступной для других модулей.

Если значение такой глобальной переменной должно часто использоваться в некоторой функции в модуле, то эта функция может создавать локальную копию: var = g.var. Тем не менее, важно понимать, что назначения var являются локальными, а глобальный g.var не может быть обновлен без ссылки на g.var явно в присваивании.

Обратите внимание, что вы также можете использовать несколько таких глобальных модулей различными подмножествами ваших модулей, чтобы держать вещи немного более жестко контролируемыми. Причина, по которой я использую короткие имена для моих модулей globals, заключается в том, чтобы избежать чрезмерного чрезмерного кодирования кода с их появлением. Имея лишь небольшой опыт, они становятся достаточно мнемоничными только с 1 или 2 символами.

По-прежнему можно выполнить назначение, скажем, g.x, когда x еще не определено в g, а другой модуль может затем получить доступ к g.x. Однако, хотя интерпретатор позволяет это, этот подход не настолько прозрачен, и я избегаю этого. По-прежнему существует вероятность случайного создания новой переменной в g в результате опечатки в имени переменной для назначения. Иногда изучение dir (g) полезно для обнаружения любых неожиданностей, которые могут возникнуть в результате такой аварии.

21
ответ дан David Vanderschel 19 August 2018 в 07:40
поделиться
  • 1
    Это интересное наблюдение решило мою проблему: «Я не использую» из g import var & quot ;, поскольку это приводит только к локальной переменной, которая инициализируется из g только во время импорта. ' Представляется разумным предположить, что «из ... import» то же самое, что и "import" Но это не так. – Curtis Yallop 20 October 2014 в 17:41

Я мог бы использовать изменяемые модули (или изменяемые) переменные с помощью словаря:

# in myapp.__init__
Timeouts = {} # cross-modules global mutable variables for testing purpose
Timeouts['WAIT_APP_UP_IN_SECONDS'] = 60

# in myapp.mod1
from myapp import Timeouts

def wait_app_up(project_name, port):
    # wait for app until Timeouts['WAIT_APP_UP_IN_SECONDS']
    # ...

# in myapp.test.test_mod1
from myapp import Timeouts

def test_wait_app_up_fail(self):
    timeout_bak = Timeouts['WAIT_APP_UP_IN_SECONDS']
    Timeouts['WAIT_APP_UP_IN_SECONDS'] = 3
    with self.assertRaises(hlp.TimeoutException) as cm:
        wait_app_up(PROJECT_NAME, PROJECT_PORT)
    self.assertEqual("Timeout while waiting for App to start", str(cm.exception))
    Timeouts['WAIT_JENKINS_UP_TIMEOUT_IN_SECONDS'] = timeout_bak

При запуске test_wait_app_up_fail фактическая продолжительность таймаута составляет 3 секунды.

0
ответ дан foudfou 19 August 2018 в 07:40
поделиться

Определите модуль (назовите его «globalbaz») и определите внутри него переменные. Все модули, использующие этот «псевдоглобал», должны импортировать модуль «globalbaz» и ссылаться на него с использованием «globalbaz.var_name»

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

Для выяснения, globalbaz.py выглядит так:

var_name = "my_useful_string"
21
ответ дан hayalci 19 August 2018 в 07:40
поделиться

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

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

5
ответ дан intuited 19 August 2018 в 07:40
поделиться

Я хотел опубликовать ответ, что есть случай, когда переменная не будет найдена.

Циклический импорт может нарушить поведение модуля.

Например:

first.py

import second
var = 1

second.py

import first
print(first.var)  # will throw an error because the order of execution happens before var gets declared.

main.py

import first

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

3
ответ дан Jonathan 19 August 2018 в 07:40
поделиться

Я задавался вопросом, можно ли избежать некоторых недостатков использования глобальных переменных (см., например, http://wiki.c2.com/?GlobalVariablesAreBad ), используя пространство имен классов, а не глобальное / модульное пространство имен для передачи значений переменных. Следующий код указывает, что эти два метода по существу идентичны. Существует небольшое преимущество в использовании пространств имен классов, как описано ниже.

Следующие фрагменты кода также показывают, что атрибуты или переменные могут динамически создаваться и удаляться как в пространствах имен глобальных / модулей, так и в пространствах имен классов.

wall.py

# Note no definition of global variables

class router:
    """ Empty class """

Я вызываю этот модуль «wall», так как он используется для отбрасывания переменных. Он будет действовать как пространство для временного определения глобальных переменных и атрибутов класса для пустого класса «маршрутизатор».

source.py

import wall
def sourcefn():
    msg = 'Hello world!'
    wall.msg = msg
    wall.router.msg = msg

Этот модуль импортирует стену и определяет единственная функция sourcefn, которая определяет сообщение и испускает его двумя разными механизмами: одна через глобальные и одна через функцию маршрутизатора. Обратите внимание, что переменные wall.msg и wall.router.message определены здесь впервые в своих соответствующих пространствах имен.

dest.py

import wall
def destfn():

    if hasattr(wall, 'msg'):
        print 'global: ' + wall.msg
        del wall.msg
    else:
        print 'global: ' + 'no message'

    if hasattr(wall.router, 'msg'):
        print 'router: ' + wall.router.msg
        del wall.router.msg
    else:
        print 'router: ' + 'no message'

Этот модуль определяет функцию destfn, который использует два разных механизма для приема сообщений, испускаемых источником. Это позволяет предположить, что переменная msg не может существовать. destfn также удаляет переменные после их отображения.

main.py

import source, dest

source.sourcefn()

dest.destfn() # variables deleted after this call
dest.destfn()

Этот модуль вызывает последовательно определенные функции. После первого вызова dest.destfn переменные wall.msg и wall.router.msg больше не существуют.

Выход из программы:

global: Hello world! Роутер: Привет, мир! global: no message router: no message

Вышеупомянутые фрагменты кода показывают, что механизмы модуля / глобального и класса / класса по существу идентичны.

Если нужно использовать множество переменных, то загрязнение пространства имен может управляться либо с помощью нескольких модулей настенного типа, например, wall1, wall2 и т. д. или путем определения нескольких классов типа маршрутизатора в одном файле. Последнее немного более аккуратное, поэтому, возможно, представляет собой предельное преимущество для использования механизма переменной класса.

0
ответ дан robertofbaycot 19 August 2018 в 07:40
поделиться

Если вам нужна глобальная кросс-модульная переменная, может быть достаточно простой глобальной переменной уровня модуля.

a.py:

var = 1

b.py:

import a
print a.var
import c
print a.var

c.py:

import a
a.var = 2

Test :

$ python b.py
# -> 1 2

Пример реального мира: Глобальный_settings.py Django (хотя в настройках Django apps используется импорт объекта django.conf.settings ).

139
ответ дан Sadly Not 19 August 2018 в 07:40
поделиться
  • 1
    Лучше, потому что это позволяет избежать возможных конфликтов пространства имен – bgw 31 October 2010 в 02:45
  • 2
    Что, если модуль, который вы импортируете, в данном случае a.py, содержит main()? Это имеет значение? – sedeh 22 August 2014 в 19:11
  • 3
    @sedeh: нет. Если a.py также запускается как сценарий, используйте в нем if __name__=="__main__" guard, чтобы избежать запуска неожиданного кода при импорте. – jfs 23 August 2014 в 13:31
  • 4
    В реальном мире вы должны быть немного осторожны с этим решением. Если программист берет вашу глобальную переменную, используя «из импорта var» (попробуйте этот вариант в c.py), они получают копию переменной во время импорта. – Paul Whipp 28 July 2015 в 23:36
  • 5
    @PaulWhipp: неверно (подсказка: используйте id() для проверки личности) – jfs 28 July 2015 в 23:38

Глобальные переменные обычно являются плохими идеями, но вы можете сделать это, назначив __builtins__:

__builtins__.foo = 'something'
print foo

. Кроме того, сами модули - это переменные, к которым вы можете получить доступ из любого модуля. Поэтому, если вы определяете модуль с именем my_globals.py:

# my_globals.py
foo = 'something'

, вы можете использовать его и из любого места:

import my_globals
print my_globals.foo

Использование модулей, а не модификация __builtins__, как правило, более чистый способ делать такие глобальные типы.

7
ответ дан spiv 19 August 2018 в 07:40
поделиться
  • 1
    __builtins__ - особенность CPython, вы действительно не должны ее использовать - лучше использовать __builtin__ (или builtins в Python3), поскольку принятый ответ показывает – Tobias Kienzler 25 March 2015 в 14:58

Вы можете передать глобалы одного модуля другому:

В модуле A:

import module_b
my_var=2
module_b.do_something_with_my_globals(globals())
print my_var

В модуле B:

def do_something_with_my_globals(glob): # glob is simply a dict.
    glob["my_var"]=3
9
ответ дан user394430 19 August 2018 в 07:40
поделиться
Другие вопросы по тегам:

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