<div dir="ltr"><div>Ciao,</div><div>una cosa (molto brutta, ma che potrebbe funzionare) è fare override dell'importatore di moduli dell'interprete:</div><div>=========================<br></div><div>import __builtin__<br>realimp = __builtin__.__import__<br>def my_import(name, globals={}, locals={}, fromlist=[]):<br> if name == 'backend' and '*' in fromlist:</div><div> raise ImportError('* import is forbidden. Module functions must be imported explicitly.')</div><div> return realimp(name, globals, locals, fromlist)<br>__builtin__.__import__ = my_import<br><br>from backend import *</div><div>=========================</div><div><br></div><div>Se, in un qualche modo, riesci a fare eseguire questo codice prima dell'import vero e proprio degli utenti, dovresti riuscire a risolvere.</div><div><br></div><div>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:</div><div><br></div><div>/ root <br></div><div> | /backend/__init__.py</div><div> | /backend/file_di_funzioni1.py</div><div> .....<br></div><div> | /frontend/__init__.py</div><div> | /frontend/file_di_funzioni1.py</div><div> .....</div><div> script_utente.py<br></div><div><br></div><div>Puoi inserire nell'__init__ dei due package frontend e banckend codice tipo questo:</div><div>==========================================================================================</div><div>import sys<br>from types import ModuleType<br><br>__version__ = "1.4.1"<br>VERSION = tuple(map(int, __version__.split(".")))<br></div><div><br></div><div># Qui vanno definite tutte le funzioni che possono essere importate dall'utente,<br></div><div>_shorcuts = {</div><div> # nome funzione : file in cui è definita<br></div><div> "backend_function": "mod",<br>}<br><br></div><div># Override della classe moduli di python, che useremo per i moduli frontend e backend<br></div><div>class MyModule(ModuleType):<br> def __getattr__(self, name):</div><div> # Override di getattribute, in modo che sia pilotato l'import delle funzioni <br></div><div> if name in _shorcuts.keys():<br> submodule = __import__(<br> "backend." + _shorcuts[name], globals(), locals(), [name]<br> )<br> return getattr(submodule, name)<br> r = ModuleType.__getattribute__(self, name)<br> return r<br><br> def __getattribute__(self, name):</div><div> # Override per intercettare l'import *<br></div><div> if name == '__all__':<br> raise ImportError('* import is forbidden. Module functions must be imported explicitly.')<br> return object.__getattribute__(self, name)<br></div><div><br></div><div># Un pò di magia per sostituire il modulo stesso (che è già stato importato) con la nostra versione del modulo<br>_, sys.modules["backend"] = sys.modules["backend"], MyModule("backend")<br></div><div># Fondamentali per rendere "backend" un package agli occhi di python<br></div><div>sys.modules["backend"].__dict__.update(<br> {<br> "__file__": __file__,<br> "__package__": "backend",<br> "__path__": __path__,<br> "__doc__": __doc__,<br> "__version__": __version__,<br> "__all__": tuple(_shorcuts.keys()),<br> "__docformat__": "restructuredtext en",<br> }<br>)</div><div>==========================================================================================</div><div><br></div><div>Fede<br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno mar 10 dic 2019 alle ore 10:35 Piergiorgio Pancino <<a href="mailto:piergiorgio.pancino@gmail.com">piergiorgio.pancino@gmail.com</a>> ha scritto:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Ciao a tutti, <div>vi scrivo per un consiglio concernente l'importazione di * da un modulo.</div><div><br></div><div>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.</div><div><br></div><div>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).</div><div>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.</div><div><br></div><div>Una delle possibili soluzioni e' chiaramente rinominare le funzioni backend, magari con un 'lib_funzione'.</div><div>Una alternativa sarebbe impedire l'import star, la domanda infatti verte su questo: e' possobile sollevare un'eccezione su questo tipo di import?</div><div>Grazie</div><div><br></div><div>Piergiorgio</div><div><br></div><div></div></div>
_______________________________________________<br>
Python mailing list<br>
<a href="mailto:Python@lists.python.it" target="_blank">Python@lists.python.it</a><br>
<a href="https://lists.python.it/mailman/listinfo/python" rel="noreferrer" target="_blank">https://lists.python.it/mailman/listinfo/python</a><br>
</blockquote></div>