简体   繁体   中英

how to avoid importing self, intra-package relationships

The directory structure is like so:

AppCenter/
main.pyw
|
|
_apps/
    __init__.py
    TabularApp.py
    UserAdministrationApp.py
    RegisterApp.py
    FnAdminApp.py
    PyUi/

The contents of __init__.py :

import sys
sys.path.insert(1, '.')


__all__ = ['TabularApp',
           'UserAdministrationApp',
           'RegisterApp',
           'FnAdminApp']

The problems pop up:

When main.pyw tries to from _apps import * . In UserAdministrationApp.py i am trying to dynamically add tooltips to some QListWidget items like so:

for app in self.__APPS__:

    app_icon = str(os.path.join(app_icons, f"{app}.png")).replace('\\', '/')
    icon = QIcon(app_icon)
    if app != self.__class__:
        ttip_txt = eval(f'_apps.{app}.__doc__')
    else:
        ttip_txt = self.__doc__

    item = QListWidgetItem(icon, app)
    item.setText(app)
    item.setToolTip(ttip_txt)
    wdg.addItem(item)

The self.__APPS__ is just a copy of _apps.__all__ . The first problem I encountered was that i would get an AttributeError saying module x has no attribute y in ttip_txt = eval(f'_apps.{app}.__doc__') I resolved this by from _apps import * in UserAdministrationApp module. At this point I had already renamed this module for testing purposes and everything worked, but when I changed the name back to UserAdministrationApp.py I got another AttributeError saying module __apps has no attribute UserAdministrationApp .

Questions

I tried reading the python import docs but nothing in it really spoke to me. I am sensing it has something to do with the script trying to import itself. But i am still intrigued by these questions:

  • Why did the import fail in the first case, when i have import _apps ?
  • Why in the second case does it not at least see itself and then produce an ImportError instead of AtributeError ?
  • What is the optimal way to handle these types of situations?

Okay I found a solution, and though i think it is a bit dirty and not in best style, it works.

First

remove the from _apps import * and just from _apps import __all__ .

Then

In initialization of the main class from the module UserAdministrationApp import in a loop skipping self.__class_.__name__

    self.__APPS__ = _apps.__all__
    self.class_name = self.__class__.__name__
    for app in self.__APPS__:
        if self.class_name != app:
            exec(f'import _apps.{app}')

Finally

    for app in self.__APPS__:

        app_icon = str(os.path.join(app_icons, f"{app}.png")).replace('\\', '/')
        icon = QIcon(app_icon)
        if app != self.class_name:
            ttip_txt = eval(f'_apps.{app}.__doc__')
        else:
            ttip_txt = self.__doc__

Having found the solution, I would still like to hear why the error was in the first place, for educational purposes. So if anybody at any time glances over this and knows how to...you are more than welcome.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM