<div dir="auto"><div dir="ltr"><div dir="ltr">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!</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Il giorno mar 10 dic 2019 alle ore 12:01 Federico Cerchiari <<a href="mailto:federicocerchiari@gmail.com" target="_blank" rel="noreferrer">federicocerchiari@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"><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></blockquote><div> </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"><div></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" target="_blank" rel="noreferrer">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" rel="noreferrer">Python@lists.python.it</a><br>
<a href="https://lists.python.it/mailman/listinfo/python" rel="noreferrer noreferrer" target="_blank">https://lists.python.it/mailman/listinfo/python</a><br>
</blockquote></div>
_______________________________________________<br>
Python mailing list<br>
<a href="mailto:Python@lists.python.it" target="_blank" rel="noreferrer">Python@lists.python.it</a><br>
<a href="https://lists.python.it/mailman/listinfo/python" rel="noreferrer noreferrer" target="_blank">https://lists.python.it/mailman/listinfo/python</a><br>
</blockquote></div></div></div>