[Python] from module import *

Federico Cerchiari federicocerchiari a gmail.com
Mar 10 Dic 2019 12:00:55 CET


Ciao,
una cosa (molto brutta, ma che potrebbe funzionare) è fare override
dell'importatore di moduli dell'interprete:
=========================
import __builtin__
realimp = __builtin__.__import__
def my_import(name, globals={}, locals={}, fromlist=[]):
    if name == 'backend' and '*' in fromlist:
        raise ImportError('* import is forbidden. Module functions must be
imported explicitly.')
    return realimp(name, globals, locals, fromlist)
__builtin__.__import__ = my_import

from backend import *
=========================

Se, in un qualche modo, riesci a fare eseguire questo codice prima
dell'import vero e proprio degli utenti, dovresti riuscire a risolvere.

In altenativa (se stai usando python3, con il 2 non os se sia possibile)
puoi intercettare la cosa facendo una sottoclasse custom del modulo di
backend/frontend, per farlo, impotizzando che tu abbia una struttura di
folder tipo questa:

/ root
  | /backend/__init__.py
  | /backend/file_di_funzioni1.py
  .....
  | /frontend/__init__.py
  | /frontend/file_di_funzioni1.py
  .....
  script_utente.py

Puoi inserire nell'__init__ dei due package frontend e banckend codice tipo
questo:
==========================================================================================
import sys
from types import ModuleType

__version__ = "1.4.1"
VERSION = tuple(map(int, __version__.split(".")))

# Qui vanno definite tutte le funzioni che possono essere importate
dall'utente,
_shorcuts = {
   # nome funzione    :  file in cui è definita
    "backend_function": "mod",
}

# Override della classe moduli di python, che useremo per i moduli frontend
e backend
class MyModule(ModuleType):
    def __getattr__(self, name):
        # Override di getattribute, in modo che sia pilotato l'import delle
funzioni
        if name in _shorcuts.keys():
            submodule = __import__(
                "backend." + _shorcuts[name], globals(), locals(), [name]
            )
            return getattr(submodule, name)
        r = ModuleType.__getattribute__(self, name)
        return r

    def __getattribute__(self, name):
        # Override per intercettare l'import *
        if name == '__all__':
            raise ImportError('* import is forbidden. Module functions must
be imported explicitly.')
        return object.__getattribute__(self, name)

# Un pò di magia per sostituire il modulo stesso (che è già stato
importato) con la nostra versione del modulo
_, sys.modules["backend"] = sys.modules["backend"], MyModule("backend")
# Fondamentali per rendere "backend" un package agli occhi di python
sys.modules["backend"].__dict__.update(
    {
        "__file__": __file__,
        "__package__": "backend",
        "__path__": __path__,
        "__doc__": __doc__,
        "__version__": __version__,
        "__all__": tuple(_shorcuts.keys()),
        "__docformat__": "restructuredtext en",
    }
)
==========================================================================================

Fede

Il giorno mar 10 dic 2019 alle ore 10:35 Piergiorgio Pancino <
piergiorgio.pancino a gmail.com> ha scritto:

> Ciao a tutti,
> vi scrivo per un consiglio concernente l'importazione di * da un modulo.
>
> Il problema si pone per il fatto che il software sul quale lavoro e'
> esposto allo scripting da parte degli utenti e quindi non e' realmente
> controllabile con delle semplici regole di buon coding.
>
> Senza andare troppo nei dettagli, ho un modulo con delle funzioni frontend
> (con print) e un modulo corrispondente con delle funzioni di backend (che
> ritornano dizionari, NamedTuple ...) queste funzioni hanno lo stesso nome e
> nel momento in cui l'utente fa: 'from backend import *' questo sovrascrive
> le funzioni frontend in maniera inaspettata (perlomeno per l'utente).
> Questo e' anche dovuto al modo in cui vengono caricati gli script utente
> che pero' al momento non e' possibile cambiare: in pratica abbiamo un
> `load_script` che elabora il file ed esegue quanto contenuto, una pratica
> non proprio pythonica, ma va mantenuta.
>
> Una delle possibili soluzioni e' chiaramente rinominare le funzioni
> backend, magari con un 'lib_funzione'.
> Una alternativa sarebbe impedire l'import star, la domanda infatti verte
> su questo: e' possobile sollevare un'eccezione su questo tipo di import?
> Grazie
>
> Piergiorgio
>
> _______________________________________________
> Python mailing list
> Python a lists.python.it
> https://lists.python.it/mailman/listinfo/python
>
-------------- parte successiva --------------
Un allegato HTML è stato rimosso...
URL: <http://lists.python.it/pipermail/python/attachments/20191210/f7e9f199/attachment.html>


Maggiori informazioni sulla lista Python