[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