[Python] from module import *

Piergiorgio Pancino piergiorgio.pancino a gmail.com
Mar 10 Dic 2019 18:43:18 CET


Grazie! una risposta davvero utile e interessante! Penso farò il monkey
patch di __import__ dato che è semplice ( e ho poco tempo), ma interessante
anche la seconda soluzione!

Il giorno mar 10 dic 2019 alle ore 12:01 Federico Cerchiari <
federicocerchiari a gmail.com> ha scritto:

> 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
>>
> _______________________________________________
> 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/fc7e46b7/attachment-0001.html>


Maggiori informazioni sulla lista Python