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 < federicocerchi...@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.panc...@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@lists.python.it >> https://lists.python.it/mailman/listinfo/python >> > _______________________________________________ > Python mailing list > Python@lists.python.it > https://lists.python.it/mailman/listinfo/python >
_______________________________________________ Python mailing list Python@lists.python.it https://lists.python.it/mailman/listinfo/python