Задать вопрос
Pyrym
@Pyrym
Python 3 и PyQt5

Python3 | Динамическое имя модуля?

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

# Python 3
# -*- coding: utf-8 -*-
import sys, importlib
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                             QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                             QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,
                             QGroupBox, QFileDialog)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
from PyQt4.QtCore import QSize
# ЦВЕТА ПОЛЕЙ
sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'")
# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.resize(200, 400) # шир / выс окна
        self.setWindowTitle('Заголовок') # Заголовок
        
        # БЛОК РАЗМЕТКИ
        self.vbox = QtGui.QVBoxLayout()
        # ---
        self.pole_vivod = QtGui.QTextEdit('')
        self.pole_vivod.setStyleSheet(sss_vivod)
        self.vbox.addWidget(self.pole_vivod)
        # ---
        self.box = QComboBox()
        self.box.addItems(['a','b1'])
        self.box.activated[str].connect(self.on_start)
        self.vbox.addWidget(self.box)
        # ---
        self.setLayout(self.vbox)
        # ---
        Window.on_start(self)
    # ЛОГИКА
    
    def on_start(self):
        name_modul = self.box.currentText()
        print('name_modul = ',name_modul)
        #import name_modul
        #importlib.import_module('name_modul')
        from importlib import import_module
        mod = import_module(name_modul)
        globals().update({k: getattr(mod, k) for k in mod.__all__})
        '''module = importlib.import_module('name_modul') # math
        globals().update(
            {n: getattr(module, n) for n in module.__all__} if hasattr(module, '__all__')
            else
            {k: v for (k, v) in module.__dict__.items() if not k.startswith('_')
            })'''
# КОНЕЦ
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()   
    window.show()
    sys.exit(app.exec_())

Выдаёт ошибку:
line 53, in on_start
    globals().update({k: getattr(mod, k) for k in mod.__all__})
AttributeError: module 'a' has no attribute '__all__'
  • Вопрос задан
  • 200 просмотров
Подписаться 1 Средний Комментировать
Решения вопроса 1
Pyrym
@Pyrym Автор вопроса
Python 3 и PyQt5
В общем решение очень простое.
Основной файл:
# Python 3
# -*- coding: utf-8 -*-

import sys, importlib
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout,
                             QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox,
                             QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy,
                             QGroupBox, QFileDialog)
from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor
from PyQt4.QtCore import QSize


# ЦВЕТА ПОЛЕЙ
sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'")

def dynamic_import(module):
    return importlib.import_module(module)

# ГРАФИКА
class Window(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        self.resize(300, 200) # шир / выс окна
        self.setWindowTitle('Заголовок') # Заголовок
        

        # БЛОК РАЗМЕТКИ
        self.vbox = QtGui.QVBoxLayout()
        # ---
        self.pole_vivod = QtGui.QTextEdit('')
        self.pole_vivod.setStyleSheet(sss_vivod)
        self.vbox.addWidget(self.pole_vivod)
        # ---
        self.box = QComboBox()
        self.box.addItems(['a','b1'])
        self.box.activated[str].connect(self.on_start)
        self.vbox.addWidget(self.box)
        # ---
        self.setLayout(self.vbox)
        # ---
        Window.on_start(self)

    # ЛОГИКА
    def on_start(self):
        name_modul = self.box.currentText()
        # print('name_modul = ',name_modul)

        mod = dynamic_import(name_modul)
        #print(mod.p)
        self.pole_vivod.setText(str(mod.p))





# КОНЕЦ
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = Window()   
    window.show() # запускает окно
    sys.exit(app.exec_())

Файл a.py:
p = ['few','efwg']
Файл b.1:
p = [2,234,214]
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@deliro
Очевидно, проблема не в импортировании. Проблема в том, что не у каждого модуля определено __all__:
In [1]: import sqlite3

In [2]: sqlite3.__all__
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-2-2be38b616c0a> in <module>()
----> 1 sqlite3.__all__

AttributeError: module 'sqlite3' has no attribute '__all__'


Получить все атрибуты модуля можно dir(module)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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