Python import module as dict

Возможно ли импортировать модуль Python (.py файл) в dict?

Любые библиотеки, которые могли бы сделать это из коробки?

Поскольку vars(module) == module.__dict__ Я получил два ответа, но принял тот, у которого есть немного больше данных. Это код, который в точности возвращает то, что я имел в виду:

import module my_stuff = module.__dict__ 

Обратите внимание, что этот dict – это фактический dict, используемый модулем для хранения его атрибутов. Если вы делаете my_stuff[‘foo’] = 3 , module имеет новый атрибут foo равный 3 .

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

thing = getattr(module, thingname) 
import module my_stuff = vars(module) 

Если вы только заботитесь о том, как вы получаете доступ к членам модуля, вы можете использовать:

my_sys = import_as_dict("sys") print my_os["sys"] 
import imp class DictProxy(object): def __init__(self, target): super(DictProxy, self).__init__() self.target = target def __getitem__(self, key): return getattr(self.target, key) def __setitem__(self, key, value): setattr(self.target, key, value) def import_as_dict(module_name): file_, pathname, description = imp.find_module(module_name) module = imp.load_module(module_name, file_, pathname, description) dict_module = DictProxy(module) return dict_module 

Использование imp для импорта будет поддерживать ваш глобальный контекст в чистоте.

Источник

Работа с модулями

Имена модулей — должны соотвествовать тем же правилам, что любые идентификаторы (алфавитные символы, цифры, подчеркивание; не ключевые слова).

То есть пробел в имени файла не допустим, даже если ОС это допускает.

Использование модулей

def spam(text): print(text, 'spam') 

Если мы хотим импортировать этот файл и вызвать функцию smap, то можем:

import вызов что значит
import b b.spam(‘a’) b — имя переменной, которая ссылается на объект модуля после его загрузки
from b import spam spam(‘a’) импорт модуля + копирование имени spam в пространство имен
from b import * spam(‘a’) импорт модуля + копирование всех имен верхнего уровня (вне def или class)

from .. * в Python3 может использоваться только на верхнем уровне.

Читайте также:  Алгоритмы программирования в php

as — псевдонимы модулей

Иногда у модуля слишком длинное имя или мы указываем имя модуля с пакетами. Тогда вместе с полным именем можно указать псевдоним, заданный с помощью as

import numpy as np import matplotlib.pyplot as plt 

Инструкции import и from — это операции присваивания

import и from — выполняемые инструкции, а не «объявления времени компиляции».

  • можно вложить в if (импортируем один модуль, иначе импортируем другой)
  • можно вложить в def (внутри функции)
  • работают только тогда, когда до них дойдет интерпретатор.

Т.е. имена и модули не доступны, пока не были выполнены нужные import.

  • import присваивает объект модуля единственному имени;
  • from присваивает одно или более имен объектам с теми же именами в другом модуле. (т.е становятся ссылками на shared объекты)
from b import x, y # скопировать два имени x = 42 # изменяется только локальная переменная х y[0] = 42 # изменяется объект по ссылке y print(x, y) # 42, [42, 2] 

Хотим изменить x в модуле b.py.

  • Это очень плохо, потому что потом не найдешь кто где менял эту х.
  • Мы не контролируем изменения.
  • Инкапсулируйте изменения через вызов функции-обертки в модуле b.py
>>> from small import x, y # Скопировать два имени >>> x = 42 # Изменить только локальное имя x >>> import small # Получить имя модуля >>> small.x = 42 # Изменить x в другом модуле 

Что лучше — import или from?

  • плюсы:
    • понятно из какого модуля используем этот атрибут (полезно при рефакторинге);
    • при одинаковых именах функциях в разных модулях мы явно прописываем из какого модуля используем функцию;
    • не может повредить существующее простанство имен (перезаписать существующую переменую х, которая теперь ссылается на атрибут модуля);
    • длинно, особенно если мы весь модуль, например, работаем с графическим модулем tkinter.
    • см. далее проблемы при reload
    • import — предпочтительнее;
    • from .. import — явно перечисляем имена;
    • from .. import * — только при одном таком импорте.

    Пространство имен модуля

    Пространство имен — место, где создаются имена.

    Атрибуты модуля — имена, которые находятся в модуле.

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

    Если в файле b.py на верхнем уровне пишем x = 1 , то имя х — это атрибут модуля b.

    x — глобальная переменная для кода внутри b.py

    К х извне можно доступиться по имени b.x

    • Инструкции модуля выполняются при первом import.
      • создается объект модуля;
      • инструкции в модуле выполняются одна за другой.
      • =
      • def
      • class
      • __dict__ — все, что есть в пространстве — для работы
      • dir — вместе с унаследованными, не полное, отсортированное — для просмотра.
      Print('starting to load. ') import sys name = 42 def func(): pass class klass: pass print('done loading.') 

      Импортируем его в интерпретаторе:

      >>> import module2 starting to load. done loading. 

      То есть код файла b.py действительно выполняется.

      Область видимости модуля после импортирования превратилась в пространство имен атрибутов объекта модуля и они доступны по модуль.атрибут:

      >>> module2.sys >>> module2.name 42 >>> module2.func > >>> module2.klass

      Внутри интерпретатора пространство имен хранится в виде обычного словаря. Разные пространства имен — разные словари.

      >>> list(module2.__dict__.keys()) ['name', '__builtins__', '__file__', '__package__', 'sys', 'klass', 'func', '__name__', '__doc__'] 
      • __file__ — имя файла, из которого был загружен модуль;
      • __name__ — имя модуля (без диреторий и расширения файла).

      Квалификация имен атрибутов

      Это доступ по объект.атрибут

      • x — простая переменная — ищется в текущих областях видимости по правилу LEGB.
      • x.y — квалифицированное имя — ищем х в текущих областях видимости, далее ищем атрибут y в объекте х (а не областях видимости)
      • x.y.z — квалифицированные пути — ищем сначала имя y в объекте х, потом имя z в объекте x.y

      Квалификация имен применяется ко всем объектам, имеющим атрибуты (модули, классы, расширения на языке С и тд.)

      Импортирование и область видимости

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

      x = 88 # x глобальна только для этого файла def f(): global x # будем изменять x в этом файле x = 99 # имена в других модулях недоступны 
      x = 11 # x глобальна только для этого файла import b # получаем доступ к именам в модуле b b.f() # изменяет переменную b.x, но не х этого файла print(x, b.x) # 11 99 

      Запустим a.py, получим 11 99.

      Когда вызвали b.f(), ее глобальной областью видимости будет тот файл, где она написана, а не там, откуда вызвана.

      Вложенные пространства имен

      Операция импорта не дает возможности из модуля b доступиться к переменным модуля а (к внешней области видимости).

      Но можно доступиться к вложенным областям видимости.

      # c.py: x = 3 # b.py: x = 2 import c print(x, c.x) # 2 3 # a.py: x = 1 import b print(x, b.x, b.c.x) # 1 2 3 

      Повторная загрузка модулей

      • модуль ищется, загружается и выполняется только при первом import;
      • при следующих import будет использоваться объект уже загруженного модуля;
      • функция imp.reload принудительно выполняет загрузку уже загруженного модуля и выполняет его код. Инструкции присваивания, которые выполняются при повтороном запуске, изменяют уже существующий объект модуля. Объект модуля изменяется, а не удаляется и создается повторно.

      Используется, для ускорения разработки. Поменяли модуль — и можем не останавливая всю программу перегрузить его и выполнить заново какие-то функции.

      Обновление сервисов, которые нельзя останавливать.

      reload повторно загружает только модули на языке Python. На языке С, например, могут загружаться динамически, но не могут перегужаться через reload.

      • Функция, а не инструкция.
      • ей передается объект модуля, а не имя.
      • не забудьте import imp
      import module # Первоначальное импортирование что-то делаем, используя этот модуль from imp import reload # Импортировать функцию reload (в 3.0) reload(module) # Загрузить обновленный модуль делаем что-то дальше, используя обновленные атрибуты модуля 
      • Функция reload запускает новый программный код в файле модуля в теку- щем пространстве имен модуля. При повторном выполнении программный код перезаписывает существующее пространство имен вместо того, чтобы удалять его и создавать вновь.
      • Инструкции присваивания на верхнем уровне файла замещают имена но- выми значениями. Например, повторный запуск инструкции def приводит к замещению предыдущей версии функции в пространстве имен модуля, выполняя повторную операцию присваивания имени функции.
      • Повторная загрузка оказывает воздействие на всех клиентов, использо- вавших инструкцию import для получения доступа к модулю. Клиенты, использовавшие инструкцию import, получают доступ к атрибутам модуля, указывая полные их имена, поэтому после повторной загрузки они будут получать новые значения атрибутов.
      • Повторная загрузка будет воздействовать лишь на тех клиентов, которые еще только будут использовать инструкцию from в будущем. Клиенты, ко- торые использовали инструкцию from для получения доступа к атрибутам в прошлом, не заметят изменений, произошедших в результате повторной загрузки, – они по-прежнему будут ссылаться на старые объекты, получен- ные до выполнения перезагрузки.

      results matching » «

      No results matching » «

      Источник

Оцените статью